Skip to content

Commit

Permalink
feat(v5-upgrade-guide): Update upgrade guide based for ClerkJS SDKs @v5
Browse files Browse the repository at this point in the history
… (#636)
  • Loading branch information
dimkl authored and alexisintech committed Mar 28, 2024
1 parent a27d9f0 commit 12ba797
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 25 deletions.
43 changes: 24 additions & 19 deletions docs/references/backend/sessions/authenticate-request.mdx
Original file line number Diff line number Diff line change
@@ -1,55 +1,60 @@
---
title: authenticateRequest()
description: Networkless method to verify a token passed from the frontend.
description: Use Clerk's Backend SDK to verify a token passed from the frontend.
---

# `authenticateRequest()`

Authenticates a token passed from the frontend. Networkless if the `secretKey` or `jwtKey` are provided. Otherwise, performs a network call to retrieve the JWKS from Clerk's Backend API.

```tsx
const authStatus = await clerkClient.authenticateRequest();
function authenticateRequest: (request: Request, options: AuthenticateRequestOptions) => Promise<RequestState>;
```

## `AuthenticateRequestParams`
## `authenticateRequest()` parameters

| Name | Type | Description |
| --- | --- | --- |
| `request` | `Request` | `Request` object |
| `options?` | [`AuthenticateRequestOptions`](#authenticate-request-options) | Optional options to configure the authentication. |

## `AuthenticateRequestOptions`

| Name | Type | Description |
| --- | --- | --- |
| `request` | `Request` | `req` object |
| `secretKey?` | `string` | The Clerk secret key from the [API Keys](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. |
| `publishableKey?` | `string` | The Clerk publishable key from the [API Keys](https://dashboard.clerk.com/last-active?path=api-keys) page in the Clerk Dashboard. |
| `domain?` | `string` | The domain for the application. For development, you can pass the localhost your application is running on. For example: `localhost:3001` |
| `isSatellite?` | `boolean` | Set to `true` if the instance is a satellite domain in a multi-domain setup. |
| `proxyUrl?` | `string` | The proxy URL from a multi-domain setup. |
| `signInUrl?` | `string` | The sign-in URL from a multi-domain setup. |
| `signInUrl?` | `string` | The sign-in URL from a multi-domain setup. |
| `afterSignInUrl?` | `string` | The URL to navigate after sign-in completion. Defaults to `/`. |
| `signUpUrl?` | `string` | The sign-up URL from a multi-domain setup. |
| `afterSignUpUrl?` | `string` | The URL to navigate after sign-up completion. Defaults to `/`. |
| `jwtKey?` | `string` | The PEM public key from the **[API Keys](https://dashboard.clerk.com/last-active?path=api-keys) page -> Advanced -> JWT public key** section of the Clerk Dashboard. |
| `audience?` | `string \| string[]` | A string or list of [audiences](https://datatracker.ietf.org/doc/html/rfc7519#section-4.1.3). |
| `frontendApi?` | `string` | The Clerk publishable key (deprecated in favor of `publishableKey`) |
| `apiKey?` | `string` | The Clerk API key (deprecated in favor of `secretKey`) |

## Examples
| `authorizedParties`| `string[]` | | A list of authorized parties. For example, `['http://localhost:4003', 'https://clerk.com']` |
| `clockSkewInMs?` | `number` | Specifies the allowed time difference (in milliseconds) between the Clerk server (which generates the token) and the clock of the user's application server when validating a token. Defaults to 5000 ms (5 seconds).|
| `jwksCacheTtlInMs?` | `number` | Specifies the allowed time (in milliseconds) the JWKs are considered valid in cache . Defaults to 3600_000 ms (1 hour).|
| `skipJwksCache?` | `boolean` | A flag to skip ignore cache and always fetch JWKs before each jwt verification.|

### `authenticateRequest({ req })`
## `authenticateRequest()` example

Takes the token passed by the frontend as a Bearer token in the Authorization header, and performs a networkless authenication. This will verify if the user is signed into the application or not.


```tsx
import { clerkClient } from '@clerk/nextjs'
import { clerkClient } from '@clerk/nextjs/server'
import { NextRequest, NextResponse } from 'next/server'

export async function GET(req: NextRequest) {
const { isSignedIn } = await clerkClient.authenticateRequest({ request: req })
const { isSignedIn } = await clerkClient.authenticateRequest(req)

if ( !isSignedIn ) {
return NextResponse.json({ status: 401 })
}

// Perform protected actions

return NextResponse.json({ message: "This is a reply" }, status: { 200 })
return NextResponse.json({ message: "This is a reply" })
}
```
127 changes: 121 additions & 6 deletions docs/upgrade-guides/upgrading-from-v4-to-v5.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,32 @@ The `API_URL` export has changed from `https://api.clerk.dev` to `https://api.cl
#### Removed the `orgs` claim as a default property of the JWT

In v4 of Clerk's SDKs, if you decode the session token that Clerk returns from the server, you'll currently find an `orgs` claim on it. It lists all the orgs associated with the given user. In v5 Clerk returns the `org_id`, `org_slug`, and `org_role` of the **active** organization.
The `orgs` claim was part of the `JwtPayload`. A few examples of where the `JwtPayload` could be found:

```typescript
import { getAuth } from '@clerk/nextjs/server;
const claims: JwtPayload = getAuth(request).sessionClaims;

import { getAuth } from '@clerk/ssr.server';
const claims: JwtPayload = (await getAuth(request)).sessionClaims;

import { getAuth } from '@clerk/fastify';
const claims: JwtPayload = (await getAuth(request)).sessionClaims;

// gatsby-plugin-clerk
const claims: JwtPayload = request.auth.sessionClaims;

import { createClerkClient } from '@clerk/backend';
const clerkClient = createClerkClient({ secretKey: '...' });
const requestState = await clerkClient.authenticateRequest(request, { publishableKey: '...' });
const claims: JwtPayload = requestState.toAuth().sessionClaims;

import { clerkClient } from '@clerk/clerk-sdk-node';
router.use((...args)=>clerkClient.expressRequireAuth()(...args));
router.get('/me', async (req, reply: Response) => {
return reply.json({ auth: req.auth });
});
```

If you would like to have your JWT return all of the user's organizations, you can create a [custom JWT template](/docs/backend-requests/making/jwt-templates) in your dashboard. Add `{ "orgs": "user.organizations" }` to it.

Expand Down Expand Up @@ -484,7 +510,47 @@ If you would like to have your JWT return all of the user's organizations, you c
+ } = await clerkClient.organizations.getOrganizationList()
```

- `clockSkewInSeconds` was renamed to `clockSkewInMs` but the default value stayed the same.
- `clockSkewInSeconds` was renamed to `clockSkewInMs` but the default value stayed the same. That change affects all the methods related to `VerifyJwtOptions`. Example:

```diff
import { verifyJwt } from '@clerk/backend/jwt'

- verifyJwt(jwt, { clockSkewInSeconds: 4000 })
+ verifyJwt(jwt, { clockSkewInMs: 4000 })

import { verifyToken } from '@clerk/backend'
- verifyToken(token, { clockSkewInSeconds: 4000 })
+ verifyToken(token, { clockSkewInMs: 4000 })

import { createClerkClient } from '@clerk/backend';
const clerkClient = createClerkClient({...});

- clerkClient.authenticateRequest(request, { clockSkewInSeconds: 4000 })
+ clerkClient.authenticateRequest(request, { clockSkewInMs: 4000 })

import { createAuthenticateRequest } from '@clerk/backend/internal`
const authenticateRequest = createAuthenticateRequest(params);

- authenticateRequest(request, { clockSkewInSeconds: 4000 })
+ authenticateRequest(request, { clockSkewInMs: 4000 })

import { signedInAuthObject } from '@clerk/backend/internal`

- signedInAuthObject({ clockSkewInSeconds: 4000 }, sessionClaims)
+ signedInAuthObject({ clockSkewInMs: 4000 }, sessionClaims)

import { signedOutAuthObject} from '@clerk/backend/internal`

- signedOutAuthObject({ clockSkewInSeconds: 4000 }, sessionClaims)
+ signedOutAuthObject({ clockSkewInMs: 4000 }, sessionClaims)
```

Also the following types are affected:
- `import type { VerifyJwtOptions } from '@clerk/backend/jwt'`
- `import type { VerifyTokenOptions } from '@clerk/backend'`
- `import type { AuthenticateRequestOptions } from '@clerk/backend/internal'`


- Replace `getPendingOrganizationInvitationList` with `getOrganizationInvitationList` and pass a `status` parameter.

```diff
Expand All @@ -505,11 +571,43 @@ If you would like to have your JWT return all of the user's organizations, you c
})
```
- The `createEmail()` method (and as such the `emails` API endpoint) has been removed. For the time being no alternative method will be provided for creating and sending emails directly from Clerk's JavaScript SDKs. If you're currently relying on this functionality and wish to update, please reach out to [Clerk's support](/support).
- The `clerkClient.__unstable_options` property used to update the internal options was removed. Create a new clerkClient instance using `createClerkClient` instead of mutating the existing. Example:

```diff
import { createClerkClient } from '@clerk/backend';

const clerkClient = createClerkClient({ ...options, secretKey: 'secretKey' });

- clerkClient.__unstable_options.secretKey = 'newSecretKey'
+ const newClerkClient = createClerkClient({ ...options, secretKey: 'newSecretKey' });
```
- The `signJwt`, `hasValidSignature`, `decodeJwt`, `verifyJwt`, `verifyToken` signatures have changed. Instead of returning a value or throwing an error those functions will **always** return a `{ data, error }` value. To keep the existing behaviour check the examples:

```diff
import { signJwt, hasValidSignature, decodeJwt, verifyJwt } from '@clerk/backend/jwt';
import { verifyToken } from '@clerk/backend'

const { data, error } = await signJwt(...)
if (error) throw error;

const { data, error } = await hasValidSignature(...)
if (error) throw error;

const { data, error } = decodeJwt(...)
if (error) throw error;

const { data, error } = await verifyJwt(...)
if (error) throw error;

const { data, error } = await verifyToken(...)
if (error) throw error;
```

Some more niche use cases and their changes:

<Accordion titles={["Removal of httpOptions", "Removal of pkgVersion", "Removal of createIsomorphicRequest & buildRequestUrl", "Use .imageUrl for image related responses/resources"]} heading="h4">
<AccordionPanel>
{/* TODO: The buildRequest is not exposed as public API. There is not a alternative at the moment*/}
The `httpOptions` parameter was removed from the `buildRequest` function. Provide this information on the returned `request` function instead.

```diff
Expand Down Expand Up @@ -544,18 +642,21 @@ Some more niche use cases and their changes:

const { data: user } = await clerkClient.users.getUser("")
```

Previously, you could access `user.profileImageUrl` and now it's `user.imageUrl`. Various image related properties were all aligned to `imageUrl`. So if you use any of these, change the property:

- `ExternalAccount.picture`
- `ExternalAccountJSON.avatar_url`
- `Organization.logoUrl`
- `OrganizationJSON.logo_url`
- `User.profileImageUrl`
- `UserJSON.profile_image_url`
- `OrganizationMembershipPublicUserData.profileImageUrl`

Or if you using the raw responses change the following properties to `image_url` in the following types:

- `ExternalAccountJSON.avatar_url`
- `OrganizationJSON.logo_url`
- `UserJSON.profile_image_url`
- `OrganizationMembershipPublicUserDataJSON.profile_image_url`
</AccordionPanel>

</Accordion>

### `@clerk/chrome-extension`
Expand Down Expand Up @@ -889,6 +990,21 @@ A couple of exported constants have been removed from `@clerk/nextjs` as you sho
</AccordionPanel>
</Accordion>

- `MembershipRole` type was replaced with `OrganizationCustomRoleKey` of Custom Roles. This type can be found in the following examples:
```jsx
import { useAuth } from '@clerk/nextjs'

const { orgRole } = useAuth();
```

To support the existing roles `admin`, `basic_member`, `guest_member` apply interface merging using the following snippet.
```jsx
interface ClerkAuthorization {
permission: '';
role: 'admin' | 'basic_member' | 'guest_member';
}
```

**Deprecated:**

- [`authMiddleware`](/docs/references/nextjs/auth-middleware). We highly recommend using [`clerkMiddleware`](/docs/references/nextjs/clerk-middleware) going forward. `clerkMiddleware` protects no routes by default and you need to add your individual routes you want to opt into protection. Here's an example of having all routes public except for everything under `/dashboard`.
Expand Down Expand Up @@ -965,7 +1081,6 @@ A couple of exported constants have been removed from `@clerk/nextjs` as you sho

For more information, read the [`useOrganization`](/docs/references/react/use-organization) docs.

- The `ClerkProviderOptionsWrapper` type was removed from the exports. Use `ClerkProviderProps` instead.
- Further changes to types:
- `redirectToUserProfile` now returns `Promise<unknown>` instead of `void`
- `redirectToOrganizationProfile` now returns `Promise<unknown>` instead of `void`
Expand Down

0 comments on commit 12ba797

Please sign in to comment.