Carry custom claims
Persisting application identity data such as a user ID across requests.
Auth.js · Function
The jwt callback runs when Auth.js creates or updates a JSON Web Token. Return the token, optionally with custom claims; use the session callback to explicitly expose selected claims to the client.
The jwt callback receives token data during sign-in and later token updates. Return the token, optionally enriched with application data; Auth.js stores the returned value in the encrypted JWT and passes it to the session callback, which must explicitly expose selected fields to the client.
jwt: (params) => Awaitable<null | JWT>| Name | Type | Description |
|---|---|---|
params | object | Callback context containing token and, depending on the event, user, account, profile, trigger, or session data. |
Awaitable<null | JWT>
import NextAuth from "next-auth"
import GitHub from "next-auth/providers/github"
export const { handlers, auth } = NextAuth({
providers: [GitHub],
callbacks: {
jwt({ token, user }) {
if (user) token.id = user.id
return token
},
session({ session, token }) {
session.user.id = token.id
return session
},
},
})The callback stores the signed-in user ID in the token; the session callback then copies it to the client-visible session.
Persisting application identity data such as a user ID across requests.
Making authorization decisions from token claims without a session database.
Passing provider credentials through Auth.js session handling to server-side backend requests.
It runs when Auth.js creates a JWT at sign-in and when the token is updated, including when a client session is accessed. The returned value is stored in the JWT and forwarded to the session callback.
Follow-up: How would you expose a custom token field to the browser? Return it from jwt, then explicitly assign token.field to a session property in session.
The token parameter is a subset of the JWT during sign-in or sign-up, including name, email, and image; on later calls it is the full JWT. The callback may return null or a JWT asynchronously.
Follow-up: Why should code distinguish initial sign-in from later calls? Initial calls can include user or account data, while later calls generally rely on the persisted token.
JWTs are encrypted by default, and the callback can support access control without a database by persisting claims in the token. Auth.js derives encryption from AUTH_SECRET unless configuration supplies another secret.
Follow-up: What should be done for a third-party API that needs JWT authentication? Use the identity provider's JWT rather than treating an Auth.js JWT as a general-purpose third-party token.
session callbackJWTAUTH_SECRETAuthConfig.adaptertrigger