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:
1function handler(req: WithAuthProp<NextApiRequest>, res: NextApiResponse) {2if (req.auth.sessionId) {3// do something with the auth object4} else {5// Respond with 401 or similar6}7}89export 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:
1function handler(req: RequireAuthProp<NextApiRequest>, res: NextApiResponse) {2// do something with the auth attributes3}45export 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:
1export class HttpError extends Error {2statusCode: number;34constructor(message: string, statusCode: number) {5super(message);67// Set the prototype explicitly.8Object.setPrototypeOf(this, HttpError.prototype);910this.statusCode = statusCode;11}12}1314export function onError(error: Error) {15// Ignore passed error, return a 40116console.log(error);17return 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);// ORexport clerk.requireAuth(handler);