Self-hosted Next.js app with Clerk Dev Auth, session not recognized in production

748 views Asked by At

I am not sure what's the next step for debugging and haven't been able to resolve my issue on Clerk's Discord or GH Issues, feels like maybe it's not a clerk issue but a Next.js issue?

I have a self-hosted next.js app in a docker container on an EC2 instance. The infra is:

CloudFlare -> Caddy reverse proxy (in docker) -> next.js app (in docker)

I've set up clerkdev and things are working well in localhost, but on production, the user session/auth data is not passed to the backend.

I've set debug: true

In my afterAuth middleware, I see that my keys are configured properly and that there is a cookieToken. In the headers, I see there's a __session entry that's the same as the cookieToken.

When the request comes in after my users signs in via Clerk, the auth param is empty:

auth {
  sessionClaims: null,
  sessionId: null,
  session: null,
  userId: null,
  user: null,
  actor: null,
  orgId: null,
  orgRole: null,
  orgSlug: null,
  organization: null,
  getToken: [Function: getToken],
  debug: [Function],
  isPublicRoute: true,
  isApiRoute: false
}

What new things can I try to debug this?

1

There are 1 answers

0
sportanova On

This issue consistently affected certain users for me, and my solution was to "manually" verify and read the userId from the __session cookie from the req object using the jose library:

import Cookies from "cookies";
const { jwtVerify, createLocalJWKSet } = require('jose');

const JWKS = createLocalJWKSet({
  "keys": [ yourClerkJWTPublicKey ],
})

const cookies = new Cookies(req);
const token = req.cookies["_parsed"].get("__session").value;
const jwt = jwtVerify(token, JWKS, {clockTolerance: "7 days"});
const userId = jwt.sub;

You can also use jsonwebtoken instead of jose since you're running on an EC2 instance. It's a little more user friendly, though it won't work in Vercel where the crypto module isn't available