Clerk logo

Clerk Docs

Ctrl + K
Go to clerk.devGet API keys

Next.js API Middleware

The Clerk Node SDK offers a way of making your Next.js API middleware aware of the Clerk Session.

You can define your handler function with the usual signature (function handler(req, res) {}) then wrap it with withAuth:

import { withAuth, WithAuthProp } from '@clerk/clerk-sdk-node';

Note: Since the request will be extended with the auth property, the signature of your handler in TypeScript would be:

1
function handler(req: WithAuthProp<NextApiRequest>, res: NextApiResponse) {
2
if (req.auth.sessionId) {
3
// do something with the auth object
4
} else {
5
// Respond with 401 or similar
6
}
7
}
8
9
export withAuth(handler);

You can also pass an onError handler to the underlying Express middleware that is called:

export withAuth(handler, { clerk, onError: error => console.log(error) });

In case you would like the request to be rejected automatically when no session exists, without having to implement such logic yourself, you can opt for the stricter variant:

import clerk, { requireAuth, RequireAuthProp } from '@clerk/clerk-sdk-node';

In this case your handler can be even simpler because the existence of the session can be assumed, otherwise theexecution will never reach your handler:

1
function handler(req: RequireAuthProp<NextApiRequest>, res: NextApiResponse) {
2
// do something with the auth attributes
3
}
4
5
export requireAuth(handler, { clerk, onError });

Note that by default the error returned will be the Clerk server error encountered (or in case of misconfiguration, the error raised by the SDK itself).

If you wish to have more control over what error code & message to respond with in this case, it's recommended to implement your own error class & handler as follows:

1
export class HttpError extends Error {
2
statusCode: number;
3
4
constructor(message: string, statusCode: number) {
5
super(message);
6
7
// Set the prototype explicitly.
8
Object.setPrototypeOf(this, HttpError.prototype);
9
10
this.statusCode = statusCode;
11
}
12
}
13
14
export function onError(error: Error) {
15
// Ignore passed error, return a 401
16
console.log(error);
17
return new HttpError('Unauthorized', 401);
18
}

The aforementioned usage pertains to the singleton case. If you would like to use a Clerk instance you instantiated yourself (e.g. named clerk), you can use the following syntax instead:

export clerk.withAuth(handler);
// OR
export clerk.requireAuth(handler);

Was this helpful?

Clerk © 2022