Răsfoiți Sursa

feat(core): Automatically set CORS exposedHeaders for bearer auth

Closes #137
Michael Bromley 6 ani în urmă
părinte
comite
f4cd71834c

+ 27 - 0
packages/core/src/bootstrap.ts

@@ -147,6 +147,7 @@ export async function preBootstrapConfig(
     }
     config = await runPluginConfigurations(config);
     registerCustomEntityFields(config);
+    setExposedHeaders(config);
     return config;
 }
 
@@ -187,6 +188,32 @@ async function getAllEntities(userConfig: Partial<VendureConfig>): Promise<Array
     return [...coreEntities, ...pluginEntities];
 }
 
+/**
+ * If the 'bearer' tokenMethod is being used, then we automatically expose the authTokenHeaderKey header
+ * in the CORS options, making sure to preserve any user-configured exposedHeaders.
+ */
+function setExposedHeaders(config: ReadOnlyRequired<VendureConfig>) {
+    if (config.authOptions.tokenMethod === 'bearer') {
+        const authTokenHeaderKey = config.authOptions.authTokenHeaderKey as string;
+        const corsOptions = config.cors;
+        if (typeof corsOptions !== 'boolean') {
+            const { exposedHeaders } = corsOptions;
+            let exposedHeadersWithAuthKey: string[];
+            if (!exposedHeaders) {
+                exposedHeadersWithAuthKey = [authTokenHeaderKey];
+            } else if (typeof exposedHeaders === 'string') {
+                exposedHeadersWithAuthKey = exposedHeaders
+                    .split(',')
+                    .map(x => x.trim())
+                    .concat(authTokenHeaderKey);
+            } else {
+                exposedHeadersWithAuthKey = exposedHeaders.concat(authTokenHeaderKey);
+            }
+            corsOptions.exposedHeaders = exposedHeadersWithAuthKey;
+        }
+    }
+}
+
 /**
  * Monkey-patches the app's .close() method to also close the worker microservice
  * instance too.

+ 5 - 1
packages/core/src/config/vendure-config.ts

@@ -49,7 +49,11 @@ export interface AuthOptions {
      *   cookie containing the session token. A browser-based client (making requests with credentials)
      *   should automatically send the session cookie with each request.
      * * 'bearer': Upon login, the token is returned in the response and should be then stored by the
-     *   client app. Each request should include the header 'Authorization: Bearer <token>'.
+     *   client app. Each request should include the header `Authorization: Bearer <token>`.
+     *
+     * Note that if the bearer method is used, Vendure will automatically expose the configured
+     * `authTokenHeaderKey` in the server's CORS configuration (adding `Access-Control-Expose-Headers: vendure-auth-token`
+     * by default).
      *
      * @default 'cookie'
      */