Switching between cookie and header-based sessions
caution
We recommend cookie-based sessions in browsers because header-based sessions require saving the access and refresh tokens in storage vulnerable to XSS attacks.
Supertokens supports 2 methods of authorizing requests:
- Based on cookies- The default in our web SDKs
- Uses HttpOnlycookies by default to prevent token theft via XSS
 
- Based on the Authorizationheader- The default in our mobile SDKs
- Uses the Authorizationheader with aBearerauth-scheme
- This can make it easier to work with API gateways and third-party services
- Preferable in mobile environments, since they can have buggy and/or unreliable cookie implementations
 
When creating/authorising sessions, the SDK has to choose to send the tokens to the frontend by cookies or custom headers. This choice is ultimately controlled by the backend, but it follows a preference set in the frontend configuration.
Frontend configuration#
You can provide a tokenTransferMethod property in the configuration of the Session recipe to set the preferred token transfer method, which will be sent to the backend with every request in the st-auth-mode header.
By default, the backend follows this preference.
- ReactJS
- Angular
- Vue
import SuperTokens from "supertokens-auth-react";
import Session from "supertokens-auth-react/recipe/session";
SuperTokens.init({
    appInfo: {
        apiDomain: "...",
        appName: "...",
        websiteDomain: "..."
    },
    recipeList: [
        Session.init({
            tokenTransferMethod: "header" // or "cookie"
        })
    ]
});
important
SuperTokens config changes need to be reflected in both supertokens-auth-react and supertokens-web-js configs.
import SuperTokens from "supertokens-auth-react";
import Session from "supertokens-auth-react/recipe/session";
SuperTokens.init({
    appInfo: {
        apiDomain: "...",
        appName: "...",
        websiteDomain: "..."
    },
    recipeList: [
        Session.init({
            tokenTransferMethod: "header" // or "cookie"
        })
    ]
});
import SuperTokens from "supertokens-web-js";
import Session from "supertokens-web-js/recipe/session";
SuperTokens.init({
    appInfo: {
        apiDomain: "...",
        appName: "...",
    },
    recipeList: [
        Session.init({
            tokenTransferMethod: "header" // or "cookie"
        })
    ],
})
important
SuperTokens config changes need to be reflected in both supertokens-auth-react and supertokens-web-js configs.
import SuperTokens from "supertokens-auth-react";
import Session from "supertokens-auth-react/recipe/session";
SuperTokens.init({
    appInfo: {
        apiDomain: "...",
        appName: "...",
        websiteDomain: "..."
    },
    recipeList: [
        Session.init({
            tokenTransferMethod: "header" // or "cookie"
        })
    ]
});
import SuperTokens from "supertokens-web-js";
import Session from "supertokens-web-js/recipe/session";
SuperTokens.init({
    appInfo: {
        apiDomain: "...",
        appName: "...",
    },
    recipeList: [
        Session.init({
            tokenTransferMethod: "header" // or "cookie"
        })
    ],
})
Backend configuration#
important
By returning a fixed value from getTokenTransferMethod you can strictly control the allowed session types regardless of the frontend config.
You can provide a getTokenTransferMethod callback in the configuration of the Session recipe.
- NodeJS
- GoLang
- Python
import SuperTokens from "supertokens-node";
import Session from "supertokens-node/recipe/session";
SuperTokens.init({
    appInfo: {
        apiDomain: "...",
        appName: "...",
        websiteDomain: "..."
    },
    recipeList: [
        Session.init({
            getTokenTransferMethod: () => "header",
        })
    ]
});
import (
    "net/http"
    "github.com/supertokens/supertokens-golang/recipe/session"
    "github.com/supertokens/supertokens-golang/recipe/session/sessmodels"
    "github.com/supertokens/supertokens-golang/supertokens"
)
func main() {
    supertokens.Init(supertokens.TypeInput{
        RecipeList: []supertokens.Recipe{
            session.Init(&sessmodels.TypeInput{
                GetTokenTransferMethod: func(req *http.Request, forCreateNewSession bool, userContext supertokens.UserContext) sessmodels.TokenTransferMethod {
                    return sessmodels.HeaderTransferMethod
                },
            }),
        },
    })
}
from supertokens_python import init, InputAppInfo
from supertokens_python.recipe import session
from supertokens_python.framework import BaseRequest
from typing import Dict, Any
def get_token_transfer_method(req: BaseRequest, for_create_new_session: bool, user_context: Dict[str, Any]):
    # OR use session.init(get_token_transfer_method=lambda *_: "header")
    return "header"
init(
    app_info=InputAppInfo(api_domain="...", app_name="...", website_domain="..."),
    framework='...', 
    recipe_list=[
        session.init(
            get_token_transfer_method=get_token_transfer_method
        )
    ]
)
note
By default, we allow both cookie and authorization bearer tokens during session verification. When creating a new session, we follow the preference of the frontend indicated by the st-auth-mode request header (set by the frontend SDK).