B2B Saas Authentication

/

Frontend SDKs

/

More Resources

/

Cookies & session management

Cookies & session management

Stytch will automatically save the Member's Session in two cookies:

  • stytch_session that will contain the opaque session token returned from the API
  • stytch_session_jwt that will contain the session JWT returned from the API

For example, if you load the SDK on https://app.mycoolsite.com it will set

  • document.cookie = "stytch_session=secret-session; domain=app.mycoolsite.com; path=/; SameSite=Lax; Secure; max-age=whenever-it-expires"
  • document.cookie = "stytch_session_jwt=eyJhxxx.xxx.xxx; domain=app.mycoolsite.com; path=/; SameSite=Lax; Secure; max-age=whenever-it-expires"

The Stytch Client allows you to configure the following directives and values related to cookie management:

{
  "cookieOptions": {
    /**
     * The name of the cookie containing the opaque Stytch session token.
     * Defaults to `stytch_session`
     */
    "opaqueTokenCookieName": "string",

    /**
     * The name of the cookie containing the opaque Stytch session token.
     * Defaults to `stytch_session_jwt`
     */
    "jwtCookieName": "string",

    /**
     * What HTTP paths the cookies should be available on.
     * Equal to configuring the `;path=${}` param in the set-cookie directive.
     * Defaults to unset.
     */
    "path": "string",
    
    /**
     * What domain the cookies should be available on.
     * Equal to configuring the `;domain=${}` param in the set-cookie directive.
     * Requires setting availableToSubdomains to have any effect.
     * Defaults to unset.
     */
    "domain": "string",

    /**
     * Whether to make the cookies available to subdomains.
     * When true, equivalent to configuring the `;domain=${window.location.host}` directive
     * When false, equivalent to leaving the directive unset
     * Defaults to false.
     */
    "availableToSubdomains": "boolean"
  }
}

To override the defaults, set the desired values in the cookieOptions and pass it as part of the optional second parameter object when initializing the Stytch Client.

import { StytchHeadlessClient } from "@stytch/vanilla-js"

const STYTCH_PUBLIC_TOKEN = 'YOUR_PUBLIC_TOKEN';

const stytchOptions = {
  cookieOptions: {
    opaqueTokenCookieName: "my_stytch_session",
    jwtCookieName: "my_stytch_session_jwt",
    path: "/",
    availableToSubdomains: true,
    domain: "app.example.com",
  }
}

const stytchClient = new StytchHeadlessClient(STYTCH_PUBLIC_TOKEN, stytchOptions)

Authenticating sessions on your backend

Since the session is stored in the site's cookies, the browser will include these cookies in the request headers to your backend if they share a domain. For any protected requests, your backend should validate either the stytch_session or stytch_session_jwt before processing with the request. The session may be validated using any Backend SDK.

Validating the opaque session in Node.js / Express.

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,
  env: stytch.envs.test,
});

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

Validating the JWT in Node.js / Express.

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,
  env: stytch.envs.test,
});

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

Overwriting the SDK managed session

In certain cases you may need to manually override the Stytch Session managed by the frontend SDK with a Session available on your backend. A common reason would be when adding custom claims to a Session which is an action that can only be done server-side.

In order to override the SDK managed Session you will need to overwrite the the stytch_session and stytch_session_jwt browser cookies. This can be done by setting the cookies in the response headers from your backend, or by setting the values directly on document.cookie. Be sure to use the same cookie names and properties which are normally set by the SDK.

In most cases, the SDK will automatically detect the new values, and proceed as normal. However, if the SDK is not properly reacting to the updated Session you can force the SDK to refresh the session.

// Call session authentication without any parameters to refresh the session in the SDK
stytchClient.session.authenticate();

HttpOnly cookies

By default, cookies are managed by the SDK running in the client and are not marked as HttpOnly. For enhanced security, you can enable the use of HttpOnly cookies for your project. This moves cookie management from the client to Stytch's backend, which makes it possible to mark cookies as HttpOnly.

When HttpOnly cookies are used, Stytch's backend will set the Domain of the cookies to the parent of your custom authentication domain. Note that cookies are accessible to the Domain specified and its subdomains. For example:

  • If your custom authentication domain is login.example.com, the Domain would be set to example.com. The cookies would be accessible to example.com and its subdomains.
  • If your custom authentication domain is login.app.example.com, the Domain would be set to app.example.com. The cookies would be accessible to app.example.com and its subdomains, but not to example.com.

Before enabling HttpOnly cookies, there are some important considerations:

  • Using HttpOnly cookies requires a custom authentication domain. This allows Stytch's backend to set cookies in a first-party context for your domain.

  • Using HttpOnly cookies will make session tokens inaccessible to client-side JavaScript. This includes opaque session tokens (stytch_session), JWT tokens (stytch_session_jwt), and intermediate session tokens (stytch_intermediate_session_token). These values will also be omitted from response bodies returned to the client from methods like stytch.session.authenticate().
  • stytch.session.getTokens() will no longer return session tokens when an active session exists. If you have any frontend code that depends on these values, you will need to change it.
  • stytch.session.updateSession() will only work if there is not an existing session token set using a cookie marked HttpOnly. If you use updateSession, make sure your cookieOptions are configured to match the domain and cookie names used by Stytch's backend.
  • When the HttpOnly cookies setting is "Enforced", Stytch will only accept browser requests for your project that use your custom authentication domain. Requests that try to access Stytch using other domains, including api.stytch.com, will be rejected.
  • cookieOptions does not apply to HttpOnly cookies.
  • HttpOnly cookies are only supported in live environments.

Enabling HttpOnly cookies

  1. In the Stytch dashboard, visit OAuth configuration and follow the instructions to add a custom domain for authentication, like login.example.com. Choose a domain that meets the needs of your application based on the considerations above.
  2. In the Stytch dashboard, under Frontend SDKs, go to "Optional configuration" and change the HttpOnly cookies setting to "Enabled". This allows Stytch to start setting HttpOnly cookies when accessed through your custom authentication domain, but still allows requests that do not use your custom authentication domain.
  3. In your application, set the endpointOptions.apiDomain option in your Stytch client configuration to your custom authentication domain. This tells the SDK to use your custom authentication domain for requests. We recommend initially changing this setting in a staging environment or for a limited set of test users.
  4. Verify that your application behaves as expected. The stytch_session and stytch_session_jwt cookies should now be marked as HttpOnly.
  5. When you have finished testing and have ensured that all users of your application are using your custom authentication domain (via the endpointOptions.apiDomain setting), change the HttpOnly cookies setting in the dashboard to "Enforced". This will block all browser SDK requests that do not use your custom authentication domain, which will prevent client-side JavaScript from accessing session tokens.

Disabling HttpOnly cookies

You can stop using HttpOnly cookies by removing the endpointOptions.apiDomain setting from your Stytch client configuration. Be aware that this will not remove existing HttpOnly cookies, which the SDK will be unable to access. To avoid disrupting existing user sessions, have your backend replace HttpOnly cookies with non-HttpOnly cookies.