Skip to content

Commit

Permalink
chore: update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
mvantellingen committed Oct 24, 2024
1 parent f21c0c8 commit 2bc8d6c
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 26 deletions.
80 changes: 54 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
26 changes: 26 additions & 0 deletions packages/apollo/README.md
Original file line number Diff line number Diff line change
@@ -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.
17 changes: 17 additions & 0 deletions packages/envelop/README.md
Original file line number Diff line number Diff line change
@@ -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.
44 changes: 44 additions & 0 deletions packages/react/README.md
Original file line number Diff line number Diff line change
@@ -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 (
<AuthProvider options={authProviderProps}>
{children}
</AuthProvider>
)
```

Use the token data

```tsx
import { useAuth } from '@labdigital/federated-token-react';

const { loading, isAuthenticated, values } = useAuth();

if (loading) {
return <div>Loading...</div>;
}
return (
<div>User is authenticated {isAuthenticated}</div>
<div>Values: {values}</div>
)
```

0 comments on commit 2bc8d6c

Please sign in to comment.