/
Contact usSee pricingStart building
    Overview
    Changelog

    Pre-built UI

    StytchB2B
      Configuration
      Callbacks
    Admin Portal
      SSO
      Org Settings
      Member Management
      SCIM
    B2BIdentityProviderBeta
      Configuration
      UI Callbacks

    Headless

    Organizations
      Get Organization
      Get Organization by Slug
      Update Organization
      Delete Organization
    Members
      Get Member
      Create Member
      Update Member
      Search Members
      Delete Member
      Reactivate Member
      Delete Member Password
      Delete Member MFA Phone Number
      Delete Member MFA TOTP
      Unlink Retired Member Email
      Update Self
      Delete Self Password
      Delete Self MFA Phone Number
      Delete Self MFA TOTP
      Unlink Retired Self Email
      Update Member (Deprecated)
      Delete Member MFA Phone Number (Deprecated)
    RBAC
      Is Authorized
      Permissions
    Email Magic Links
      Login or Signup
      Invite
      Authenticate
      Send Discovery Email
      Authenticate Discovery Magic Link
    Email One-time Passcodes (OTPs)
      Login or Signup
      Authenticate OTP
      Send Discovery Email OTP
      Authenticate Discovery Email OTP
    OAuth
      Start OAuth Flow
      Google One Tap
      Authenticate
      Start Discovery OAuth Flow
      Discovery Authenticate
    Session Management
      Get Session
      Authenticate Session
      Revoke Session
      Update Session
      Exchange Session
      Get Tokens
      Revoke Sessions for Member
    SSO
      Start SSO Flow
      Authenticate
      Get SSO Connections
      Discover SSO Connections
      Delete SSO Connection
      Create SAML Connection
      Update SAML Connection
      Update SAML Connection by Metadata URL
      Delete Verification Certificate
      Create OIDC Connection
      Update OIDC Connection
      Create External Connection
      Update External Connection
    Discovery
      List Discovered Organizations
      Create Organization via Discovery
      Exchange Intermediate Session
    Passwords
      Authenticate
      Reset by Email Start
      Reset by Email
      Reset by Existing Password
      Reset by Session
      Strength Check
    • Discovery

      • Authenticate
        Reset by Email Start
        Reset by Email
    SCIM
      Create SCIM Connection
      Update SCIM Connection
      Delete SCIM Connection
      Get SCIM Connection
      SCIM Token Rotation Start
      SCIM Token Rotation Complete
      SCIM Token Rotation Cancel
      Get SCIM Connection Groups
    Multi-Factor Authentication
    • One-Time Passcodes

      • SMS Send
        SMS Authenticate
    • Time-Based One-Time Passcodes

      • TOTP Create
        TOTP Authenticate
    • Recovery Codes

      • Recovery Codes Recover
        Rotate Recovery Codes
        Get Recovery Codes
    Impersonation
      Authenticate

    More Resources

    Cookies & session management
    SWR & caching
    TypeScript
Get support on SlackVisit our developer forum

Contact us

B2B Saas Authentication

/

Frontend SDKs

/

More Resources

/

Cookies & session management

Cookies & session management

For additional information about how to manage sessions when using our frontend JavaScript SDK, check out our Frontend sessions guide.

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"

If you load the SDK on localhost, we will not mark the cookie as secure.

Cookie Configuration Options

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 { StytchB2BHeadlessClient } from "@stytch/vanilla-js/b2b/headless"

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 StytchB2BHeadlessClient(STYTCH_PUBLIC_TOKEN, stytchOptions)

cookieOptions does not apply to HttpOnly cookies.

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 domain. Note that cookies are accessible to the Domain specified and its subdomains. For example:

  • If your custom 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 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 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 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. Configure a custom domain for your application (see our guide).
  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 domain, but still allows requests that do not use your custom domain.
  3. In your application, set the endpointOptions.apiDomain option in your Stytch client configuration to your custom domain. This tells the SDK to use your custom 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 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 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.

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.B2BClient({
  project_id: process.env.STYTCH_PROJECT_ID,
  secret: process.env.STYTCH_SECRET,
});

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.B2BClient({
  project_id: process.env.STYTCH_PROJECT_ID,
  secret: process.env.STYTCH_SECRET,
});

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

Cookie Configuration Options

HttpOnly cookies

Enabling HttpOnly cookies

Disabling HttpOnly cookies

Authenticating sessions on your backend

Validating the opaque session in Node.js / Express.

Validating the JWT in Node.js / Express.