Skip to content
11 changes: 8 additions & 3 deletions docs/_partials/authenticate-req.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@
import { createClerkClient } from '@clerk/backend'

export async function GET(req: Request) {
// Initialize the JS Backend SDK
// This varies depending on the SDK you're using
// https://clerk.com/docs/js-backend/getting-started/quickstart
const clerkClient = createClerkClient({
secretKey: process.env.CLERK_SECRET_KEY,
publishableKey: process.env.CLERK_PUBLISHABLE_KEY,
})

const { isSignedIn } = await clerkClient.authenticateRequest(req, {
jwtKey: process.env.CLERK_JWT_KEY,
// Use the `authenticateRequest()` method to verify the token
const { isAuthenticated } = await clerkClient.authenticateRequest(req, {
authorizedParties: ['https://example.com'],
jwtKey: process.env.CLERK_JWT_KEY,
})

if (!isSignedIn) {
// Protect the route from unauthenticated users
if (!isAuthenticated) {
return Response.json({ status: 401 })
}

Expand Down
2 changes: 1 addition & 1 deletion docs/_partials/backend/usage.mdx
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
> [!NOTE]
> Importing `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties).
> Using `clerkClient` varies based on your framework. Refer to the [JS Backend SDK overview](/docs/js-backend/getting-started/quickstart) for usage details, including guidance on [how to access the `userId` and other properties](/docs/js-backend/getting-started/quickstart#get-the-user-id-and-other-properties).
200 changes: 155 additions & 45 deletions docs/guides/configure/auth-strategies/social-connections/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ Use the following tabs to see how to add additional OAuth scopes to the `<UserPr

You can use a social provider's OAuth access token to access user data from that provider in addition to their data from Clerk.

To retrieve the OAuth access token for a user, use the [`getUserOauthAccessToken()`](/docs/references/backend/user/get-user-oauth-access-token) method from the JS Backend SDK. This method must be used in a server environment, and cannot be run on the client.
To retrieve the OAuth access token for a user, use the [`getUserOauthAccessToken()`](/docs/references/backend/user/get-user-oauth-access-token) method from the JS Backend SDK. **This method must be used in a server environment, and cannot be run on the client.**

Clerk ensures that the OAuth access token will be always fresh so that you don't have to worry about refresh tokens.

Expand All @@ -84,50 +84,160 @@ The following example demonstrates how to retrieve the OAuth access token for a
- The user has already connected their Notion account to your application.
- The user has the correct permissions to access the Notion API.

The example is written for Next.js App Router, but is supported by any React-based framework.

```tsx {{ filename: 'app/api/notion/route.tsx' }}
import { auth, clerkClient } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'

export async function GET() {
const { isAuthenticated, userId } = await auth()

if (!isAuthenticated) {
return NextResponse.json({ message: 'User not found' })
}

// Get the OAuth access token for the user
const provider = 'notion'

const client = await clerkClient()

const clerkResponse = await client.users.getUserOauthAccessToken(userId, provider)

const accessToken = clerkResponse[0].token || ''

if (!accessToken) {
return NextResponse.json({ message: 'Access token not found' }, { status: 401 })
}

// Fetch the user data from the Notion API
// This endpoint fetches a list of users
// https://developers.notion.com/reference/get-users
const notionUrl = 'https://api.notion.com/v1/users'

const notionResponse = await fetch(notionUrl, {
headers: {
Authorization: `Bearer ${accessToken}`,
'Notion-Version': '2022-06-28',
},
})

// Handle the response from the Notion API
const notionData = await notionResponse.json()

return NextResponse.json({ message: notionData })
}
```
**If your SDK isn't listed, you can use the comments in the example to help you adapt it to your SDK.**

<Tabs items={["Next.js", "Express", "JS Backend SDK"]}>
<Tab>
```tsx {{ filename: 'app/api/notion/route.tsx' }}
import { auth, clerkClient } from '@clerk/nextjs/server'
import { NextResponse } from 'next/server'

export async function GET() {
// The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
// Accessing the `Auth` object differs depending on the SDK you're using
// https://clerk.com/docs/references/backend/types/auth-object#how-to-access-the-auth-object
const { isAuthenticated, userId } = await auth()

// Protect the route from unauthenticated users
if (!isAuthenticated) {
return NextResponse.json({ message: 'User not found' })
}

// Use the JS Backend SDK to get the OAuth access token for the user
const provider = 'notion'

// Initialize the JS Backend SDK
// This varies depending on the SDK you're using
// https://clerk.com/docs/js-backend/getting-started/quickstart
const client = await clerkClient()

// Use the JS Backend SDK to get the user's OAuth access token
const clerkResponse = await client.users.getUserOauthAccessToken(userId, provider)
const accessToken = clerkResponse.data[0].token || ''
if (!accessToken) {
return NextResponse.json({ message: 'Access token not found' }, { status: 401 })
}

// Fetch the user data from the Notion API
// This endpoint fetches a list of users
// https://developers.notion.com/reference/get-users
const notionUrl = 'https://api.notion.com/v1/users'

const notionResponse = await fetch(notionUrl, {
headers: {
Authorization: `Bearer ${accessToken}`,
'Notion-Version': '2022-06-28',
},
})

// Handle the response from the Notion API
const notionData = await notionResponse.json()

return NextResponse.json({ message: notionData })
}
```
</Tab>

<Tab>
```js {{ filename: 'notion.js' }}
import { createClerkClient, getAuth } from '@clerk/express'
import express from 'express'

const app = express()
// Initialize the JS Backend SDK
// This varies depending on the SDK you're using
// https://clerk.com/docs/js-backend/getting-started/quickstart
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })

app.get('/user', async (req, res) => {
// The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
// Accessing the `Auth` object differs depending on the SDK you're using
// https://clerk.com/docs/references/backend/types/auth-object#how-to-access-the-auth-object
const { isAuthenticated, userId } = getAuth(req)

// Protect the route from unauthenticated users
if (!isAuthenticated) {
res.status(401).json({ error: 'User not authenticated' })
}

// Use the JS Backend SDK to get the user's OAuth access token
const provider = 'notion'
const clerkResponse = await clerkClient.users.getUserOauthAccessToken(userId, provider)
const accessToken = clerkResponse.data[0].token || ''

if (!accessToken) {
res.status(401).json({ error: 'Access token not found' })
}

// Fetch the user data from the Notion API
// This endpoint fetches a list of users
// https://developers.notion.com/reference/get-users
const notionUrl = 'https://api.notion.com/v1/users'

const notionResponse = await fetch(notionUrl, {
headers: {
Authorization: `Bearer ${accessToken}`,
'Notion-Version': '2022-06-28',
},
})

// Handle the response from the Notion API
const notionData = await notionResponse.json()

res.json(notionData)
})
```
</Tab>

<Tab>
```js
import { createClerkClient } from '@clerk/backend'

// Initialize the JS Backend SDK
// This varies depending on the SDK you're using
// https://clerk.com/docs/js-backend/getting-started/quickstart
const clerkClient = createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY })

async function getNotionData(request) {
// The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
// Accessing the `Auth` object differs depending on the SDK you're using
// https://clerk.com/docs/references/backend/types/auth-object#how-to-access-the-auth-object
const { isAuthenticated, userId } = request.auth

// Protect the route from unauthenticated users
if (!isAuthenticated) {
return null
}

// Use the JS Backend SDK to get the user's OAuth access token
const provider = 'notion'
const clerkResponse = await clerkClient.users.getUserOauthAccessToken(userId, provider)
const accessToken = clerkResponse.data[0].token || ''
if (!accessToken) {
return null
}

// Fetch the user data from the Notion API
// This endpoint fetches a list of users
// https://developers.notion.com/reference/get-users
const notionUrl = 'https://api.notion.com/v1/users'

const notionResponse = await fetch(notionUrl, {
headers: {
Authorization: `Bearer ${accessToken}`,
'Notion-Version': '2022-06-28',
},
})

// Handle the response from the Notion API
const notionData = await notionResponse.json()

// Return the Notion data
return notionData
}
```
</Tab>
</Tabs>

## Add a social connection after sign-up

Expand Down
2 changes: 1 addition & 1 deletion docs/guides/organizations/metadata.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,6 @@ There are two ways to set organization metadata:

### Using the JS Backend SDK

To ease the flow of setting metadata, Clerk provides the `updateOrganizationMetadata()` and `updateOrganizationMembershipMetadata()` methods from the [JS Backend](/docs/js-backend/getting-started/quickstart), which is a wrapper around the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}.
To ease the flow of setting metadata, Clerk provides the `updateOrganizationMetadata()` and `updateOrganizationMembershipMetadata()` methods from the [JS Backend SDK](/docs/js-backend/getting-started/quickstart), which is a wrapper around the [Backend API](/docs/reference/backend-api){{ target: '_blank' }}.

<Include src="_partials/metadata-callout" />
Loading