From fe12fe12a701d3b1e0a7b88ed839e50a9d082fae Mon Sep 17 00:00:00 2001 From: Michael van Tellingen Date: Thu, 24 Oct 2024 11:35:27 +0200 Subject: [PATCH] chore: update documentation --- README.md | 80 +++++++++++++++++++++++++------------- packages/apollo/README.md | 26 +++++++++++++ packages/envelop/README.md | 17 ++++++++ packages/react/README.md | 44 +++++++++++++++++++++ 4 files changed, 141 insertions(+), 26 deletions(-) create mode 100644 packages/apollo/README.md create mode 100644 packages/envelop/README.md create mode 100644 packages/react/README.md diff --git a/README.md b/README.md index db21be4..9ed19df 100644 --- a/README.md +++ b/README.md @@ -3,45 +3,73 @@ [![npm](https://img.shields.io/npm/v/@labdigital/federated-token.svg)](https://www.npmjs.com/package/@labdigital/federated-token) This package provides support for using JWT tokens for clients and passing -that information to all federated services. The JWT token includes a JWE token -for sensitive information like the client specific access tokens of third party -systems. +that information to all federated services (upstream and downstream). -It provides three Apollo specific classes: +## Packages + - `@labdigital/federated-token` - The core package that provides the token + handling and token sources. + - `@labdigital/federated-token-apollo` - A plugin for Apollo Server (and gateway). + - `@labdigital/federated-token-envelop` - An Envelop plugin for e.g. Yoga. + - `@labdigital/federated-token-react` - A React context provider for managing the + token state in a React application. -- `GatewayAuthPlugin` - An Apollo plugin for the GraphQL gateway that verifies - the signature of the token passed and decrypts the embedded JWE property. It - stores the verified and decrypted token on the context as `federatedToken`. -- `FederatedGraphQLDataSource` - An Apollo GraphQL data source used in the - GraphQL Gateway which passes the `federatedToken` from the context to the - datasource (federated service) as `x-access-token` HTTP header. +# Upgrading from 0.x to 1.x +The 1.x release is a considerable rewrite of the package to allow better +distinction between authenticated users and guest users. This primarily impacts +the `CookieTokenSource` This allows you to control on your CDN which cookies are +white-listed and which are not. -- `FederatedAuthPlugin` - An Apollo plugin for federated services that reads - the token passed in the `x-access-token` header and stores it on the context - as `federatedToken`. +For ease of implementation and migrating users with existing cookies you need to +make sure that both the refresh-token and the refresh-token-exists cookie names +match the old names. -When a federated services creates a new token (when non exist) it can also -return a refresh token in the `x-refresh-token` header. The gateway will then -encrypt all refresh tokens and encrypt them before passing them to the client -as `x-refresh-token` header. +```ts +const server = new ApolloServer({ + // ... + plugins: [ + // ... + new GatewayAuthPlugin({ + signer: createTokenSigner(), + source: new CompositeTokenSource([ + new CookieTokenSource({ + refreshTokenPath: "/auth/graphql", + secure: true, + sameSite: "Lax", + publicDomainFn: (request: express.Request) => config.COOKIE_DOMAIN, + cookieNames: { + refreshToken: "authRefreshToken", + guestRefreshTokenExists: "authRefreshTokenExist", + } + }), + new HeaderTokenSource(), + ]), + }), + // ... + ], + // ... +}); +``` -# Token sources +# Token sources Public tokens can be passed via either HTTP headers or cookies. For browser clients cookies are the preferred way since these are easiest to store safely in the browser using a combination of HTTP_ONLY cookies and non-HTTP_ONLY cookies. -## Cookie Token Source -This token source is used for browser clients to safely store the token. It is -implemented via 4 cookies: +## Cookie Token Source +This token source is used for browser clients to safely store the token. It +differentiates the tokens using a prefix for user tokens and guest tokens. -- `accessToken` - The JWT token -- `tokenFingerprint` - A random string that is used to protect the AccessToken - cookie from CSRF attacks. It is stored as HTTP_ONLY cookie. +- `userToken` / `guestToken` - The JWT token, HTTP_ONLY +- `userData` / `guestData` - Value data for keeping state, can be used to for + example store some user information so it can be used in a frontend, + non-HTTP_ONLY - `refreshToken` - The refresh token, if any. It is stored as HTTP_ONLY cookie. -- `guestRefreshTokenExists` - A boolean value that indicates if a refresh token - exists for the user. It is used to determine if the user is new or not. +- `userRefreshTokenExists` / `guestRefreshTokenExists` - A boolean value that +indicates if a refresh token exists. It is used to determine if we can refresh +an existing token. + Note that this expects the "cookie-parser" express middleware to be used. diff --git a/packages/apollo/README.md b/packages/apollo/README.md new file mode 100644 index 0000000..583fb4a --- /dev/null +++ b/packages/apollo/README.md @@ -0,0 +1,26 @@ +# Federated Token - Apollo Plugin + +[![npm](https://img.shields.io/npm/v/@labdigital/federated-token.svg)](https://www.npmjs.com/package/@labdigital/federated-token) + +This package provides support for both Apollo Server (including Gateway). It +processes the token and forwards it to downstream services and also reads +new/updated tokens from downstream services. + +It provides three Apollo specific classes: + +- `GatewayAuthPlugin` - An Apollo plugin for the GraphQL gateway that verifies + the signature of the token passed and decrypts the embedded JWE property. It + stores the verified and decrypted token on the context as `federatedToken`. + +- `FederatedGraphQLDataSource` - An Apollo GraphQL data source used in the + GraphQL Gateway which passes the `federatedToken` from the context to the + datasource (federated service) as `x-access-token` HTTP header. + +- `FederatedAuthPlugin` - An Apollo plugin for federated services that reads + the token passed in the `x-access-token` header and stores it on the context + as `federatedToken`. + +When a federated services creates a new token (when non exist) it can also +return a refresh token in the `x-refresh-token` header. The gateway will then +encrypt all refresh tokens and encrypt them before passing them to the client +as `x-refresh-token` header. diff --git a/packages/envelop/README.md b/packages/envelop/README.md new file mode 100644 index 0000000..8eb44c9 --- /dev/null +++ b/packages/envelop/README.md @@ -0,0 +1,17 @@ +# Federated Token - Envelop Plugin + +[![npm](https://img.shields.io/npm/v/@labdigital/federated-token.svg)](https://www.npmjs.com/package/@labdigital/federated-token) + +This packages provides an Envelop plugin so that for example Yoga can be used as +a federated service. I + +It provides three Apollo specific classes: + +- `federatedAuthPlugin` - An Apollo plugin for federated services that reads + the token passed in the `x-access-token` header and stores it on the context + as `federatedToken`. + +When a federated services creates a new token (when non exist) it can also +return a refresh token in the `x-refresh-token` header. The gateway will then +encrypt all refresh tokens and encrypt them before passing them to the client +as `x-refresh-token` header. diff --git a/packages/react/README.md b/packages/react/README.md new file mode 100644 index 0000000..cab567c --- /dev/null +++ b/packages/react/README.md @@ -0,0 +1,44 @@ +# Federated Token - React Provider + +The package `@labdigital/federated-token-react` provides a React context provider +to manage the token state in a React application. + +# Usage + +Register the `AuthProvider` in your application. This will provide the token to +all components in the application. + +```tsx +import { + AuthProvider, + AuthProviderProps, +} from "@labdigital/federated-token-react"; + +const authProviderProps: AuthProviderProps = { + logoutMutation: JSON.stringify({ + query: "mutation { clearToken }", + }), + refreshTokenMutation: JSON.stringify({ + query: "mutation { refreshToken }", + }), + authEndpoint: `${clientApiHostname}/auth/graphql`, +}; + +return {children}; +``` + +Use the token data + +```tsx +import { useAuth } from '@labdigital/federated-token-react'; + +const { loading, isAuthenticated, values } = useAuth(); + +if (loading) { + return
Loading...
; +} +return ( +
User is authenticated {isAuthenticated}
+
Values: {values}
+) +```