Skip to main content

Use case

  • Protect server-side endpoints: Validate either the session_token or session_jwt on requests to your backend before proceeding with the request.
  • Backend authorization checks: Enforce RBAC permissions and perform server-side user authorization checks before proceeding with the request.

JWT vs. session token validation

Since session_jwt and session_token are stored in the site’s cookies, the browser will include these cookies in the request headers to your backend if they share a domain. Select between validating a JWT or session token:
Using JSON Web Tokens (JWT) over opaque session tokens allows you to validate the token locally entirely within your backend service, which is significantly faster than communicating with Stytch’s API on every user session validation check.

Reasons to use JWTs

  • Minimize latency: JWTs can be locally validated to authenticate sessions without an API call (until it expires).
  • Authorize actions outside your app: JWTs contain standard claims and information about the User Session.

Using the Stytch SDK

JWT validation flow
1

Initialize the SDK

Upon initialization, the Stytch SDK client will automatically retrieve and cache your JSON Web Key Set (JWKS) for use in local JWT validation.
Persist the SDK client instead of reinitializing it between requests so your JWKS is only fetched once.
3

Using authenticateJwt() example

Node.js
const express = require('express');
const cookieParser = require('cookie-parser');

const app = express();
app.use(cookieParser());
app.use(authenticateStytchSession);

const client = new stytch.Client({
  project_id: process.env.STYTCH_PROJECT_ID,
  secret: process.env.STYTCH_SECRET,
});

const authenticateStytchSession = (req, res, next) => {
return client.sessions.authenticateJwt({ session_jwt: req.cookies['stytch_session_jwt'] })
  .then(session => {
    req.stytchSession = session;
    return next();
  })
  .catch(next)
};

Retrieving user data when validating locally

authenticateJwt() does not return the full User object when validated locally. If you need data from the User object to complete additional authorization checks or any other additional action, use custom claims to add it to the JWT itself.

Using custom backend JWT validation

Stytch JWTs are compatible with other standard JWT validation libraries. You’ll need to:
  • Implement logic to fall back to Stytch’s Authenticate Session endpoint when the JWT is expired. You can refer to the Authenticate JWT method for what that logic might look like.
  • Supply your validation library the Stytch Get JWKS endpoint for JWKS rotation. Otherwise, your application should decide which JWKS to use for validation by inspecting the JWT and JWKS kid value.
We strongly recommend using our backend SDKs (available in Python, Node, Ruby, Go, and Java) for JWT validation. Our libraries handle the logic to authenticate JWTs locally and automatically fall back to the Stytch API when the JWT is expired.

JSON Web Key Set (JWKS) rotation

Stytch automatically rotates your JWKS every 6 months for security purposes. Newly minted JWTs will be signed using the new key set. Both key sets will be returned by the Get JWKS endpoint for a 1 month grace period.
  • There will be a 5 minute period where some JWTs will be signed by the old JWKS and some by the new due to the JWT set lifetime.
  • Match the kid value of the JWT and JWKS to determine the correct JWKS to use for validation.
Stytch’s backend SDKs handle JWKS rotation for you automatically.

Next steps

  • Storing JWTs on the frontend