Verify OAuth access tokens in your React Router application with Clerk
When building a resource server that needs to accept and verify OAuth access tokens issued by Clerk, it's crucial to verify these tokens on your backend to ensure the request is coming from an authenticated client.
Clerk provides a built-in getAuth()
function that supports token validation via the acceptsToken
parameter. This lets you specify which type(s) of token your API route should accept in your React Router app.
By default, acceptsToken
is set to session_token
, which means OAuth tokens will not be accepted unless explicitly configured. You can pass either a single token type or an array of token types to acceptsToken
. To know more about the supported token types, see the getAuth()
parameters documentation.
Examples
Here is an example using getAuth()
to authenticate OAuth access tokens issued by Clerk in a React Router app:
- It only accepts OAuth tokens
(acceptsToken: 'oauth_token')
from the incoming request. - If the token is invalid or missing, it throws a
401
error indicating the OAuth token is invalid. - If valid, it returns the authenticated user’s subject and their associated scopes for further authorization.
import type { LoaderFunction } from 'react-router-dom'
import { getAuth } from '@clerk/react-router/ssr.server'
export const clerkAuth: LoaderFunction = async ({ request }) => {
const authObject = await getAuth(request, {
acceptsToken: 'oauth_token',
})
if (!authObject.subject) {
throw new Response('OAuth access token is invalid', { status: 401 })
}
return { subject: authObject.subject, scopes: authObject.scopes }
}
Here is an example using getAuth()
to protect the route based on token type in your React Router app using Clerk’s SDK:
- It accepts any token type
(acceptsToken: 'any')
from the request. - If the token is a
session_token
, it logs that the request is from a user session. - Otherwise, it logs that the request uses a machine token and specifies its type.
import { getAuth } from '@clerk/react-router/ssr.server'
import type { Route } from './+types/profile'
export async function loader(args: Route.LoaderArgs) {
const authObject = await getAuth(args, { acceptsToken: 'any' })
if (authObject.tokenType === 'session_token') {
console.log('this is session token from a user')
} else {
console.log('this is some other type of machine token')
console.log('more specifically, a ' + authObject.tokenType)
}
return {}
}
Feedback
Last updated on