Browse Source

docs: Docs on connecting to API

Michael Bromley 2 years ago
parent
commit
7e142fc8c4
1 changed files with 87 additions and 3 deletions
  1. 87 3
      docs/docs/guides/storefront/connect-api/index.mdx

+ 87 - 3
docs/docs/guides/storefront/connect-api/index.mdx

@@ -25,13 +25,97 @@ GraphQL requests are made over HTTP, so you can use any HTTP client such as the
 * [graphql-request](https://github.com/jasonkuhrt/graphql-request): Minimal GraphQL client supporting Node and browsers for scripts or simple apps
 * [TanStack Query](https://tanstack.com/query/latest): Powerful asynchronous state management for TS/JS, React, Solid, Vue and Svelte, which can be combined with `graphql-request`.
 
-Here are some examples of how to use these clients to connect to the Shop API:
+
+## Managing Sessions
+
+Vendure supports two ways to manage user sessions: **cookies** and **bearer token**. The method you choose depends on your requirements, and is specified by the [`authOptions.tokenMethod` property](/reference/typescript-api/auth/auth-options/#tokenmethod) of the VendureConfig. By default, both are enabled on the server:
+
+```ts title="src/vendure-config.ts"
+import { VendureConfig } from '@vendure/core';
+
+export const config: VendureConfig = {
+    // ...
+    authOptions: {
+        // highlight-next-line
+        tokenMethod: ['bearer', 'cookie'],
+    },
+};
+```
+
+### Cookie-based sessions
+
+Using cookies is the simpler approach for browser-based applications, since the browser will manage the cookies for you automatically.
+
+1. Enable the `credentials` option in your HTTP client. This allows the browser to send the session cookie with each request.
+
+    For example, if using a fetch-based client (such as [Apollo client](https://www.apollographql.com/docs/react/recipes/authentication/#cookie)) you would set `credentials: 'include'` or if using [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials), you would set `withCredentials: true`
+
+2. When using cookie-based sessions, you should set the [`authOptions.cookieOptions.secret` property](/reference/typescript-api/auth/cookie-options#secret) to some secret string which will be used to sign the cookies sent to clients to prevent tampering. This string could be hard-coded in your config file, or (better) reside in an environment variable:
+
+    ```ts title="src/vendure-config.ts"
+    import { VendureConfig } from '@vendure/core';
+
+    export const config: VendureConfig = {
+        // ...
+        authOptions: {
+            tokenMethod: ['bearer', 'cookie'],
+            // highlight-start
+            cookieOptions: {
+                secret: process.env.COOKIE_SESSION_SECRET
+            }
+            // highlight-end
+        }
+    }
+    ```
+
+:::caution
+**SameSite cookies**
+
+When using cookies to manage sessions, you need to be aware of the SameSite cookie policy. This policy is designed to prevent cross-site request forgery (CSRF) attacks, but can cause problems when using a headless storefront app which is hosted on a different domain to the Vendure server. See [this article](https://web.dev/samesite-cookies-explained/) for more information.
+:::
+
+### Bearer-token sessions
+
+Using bearer tokens involves a bit more work on your part: you'll need to manually read response headers to get the token, and once you have it you'll have to manually add it to the headers of each request.
+
+The workflow would be as follows:
+
+1. Certain mutations and queries initiate a session (e.g. logging in, adding an item to an order etc.). When this happens, the response will contain a HTTP header which [by default is called `'vendure-auth-token'`](/reference/typescript-api/auth/auth-options#authtokenheaderkey).
+2. So your http client would need to check for the presence of this header each time it receives a response from the server.
+3. If the `'vendure-auth-token'` header is present, read the value and store it because this is your bearer token.
+4. Attach this bearer token to each subsequent request as `Authorization: Bearer <token>`.
+
+Here's a simplified example of how that would look:
+
+```ts
+let token: string | undefined = localStorage.getItem('token')
+
+export async function request(query: string, variables: any) {
+     // If we already know the token, set the Authorization header.
+     const headers = token ? { Authorization: `Bearer ${token}` } : {};
+
+     const response = await someGraphQlClient(query, variables, headers);
+
+     // Check the response headers to see if Vendure has set the
+     // auth token. The header key "vendure-auth-token" may be set to
+     // a custom value with the authOptions.authTokenHeaderKey config option.
+     const authToken = response.headers.get('vendure-auth-token');
+     if (authToken != null) {
+         token = authToken;
+     }
+     return response.data;
+}
+```
+
+
 
 ## Examples
 
+Here are some examples of how to set up clients to connect to the Shop API:
+
 ### Fetch
 
-First we'll look at a plain Fetch-based implementation, to show you that there's no special magic to a GraphQL request - it's just a POST request with a JSON body.
+First we'll look at a plain [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)-based implementation, to show you that there's no special magic to a GraphQL request - it's just a POST request with a JSON body.
 
 
 <Tabs>
@@ -127,7 +211,7 @@ query(document, {
 </TabItem>
 </Tabs>
 
-As you can see, the basic implementation with `fetch` is quite straightforward. It is also lacking some features that other,
+As you can see, the basic implementation with `fetch` is quite straightforward. However, it is also lacking some features that other,
 dedicated client libraries will provide.
 
 ### Apollo Client