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
HttpOnly
cookies by default to prevent token theft via XSS
- Based on the
Authorization
header- The default in our mobile SDKs
- Uses the
Authorization
header with aBearer
auth-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 configurationYou 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
You will have to make changes to the auth route config, as well as to the supertokens-web-js
SDK config at the root of your application:
This change is in your auth route config.
// this goes in the auth route config of your frontend app (once the pre built UI script has been loaded)
supertokensUIInit("supertokensui", {
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
supertokensUISession.init({
tokenTransferMethod: "header" // or "cookie"
})
]
});
This change goes in the supertokens-web-js
SDK config at the root of your application:
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"
})
],
})
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"
})
]
});
You will have to make changes to the auth route config, as well as to the supertokens-web-js
SDK config at the root of your application:
This change is in your auth route config.
// this goes in the auth route config of your frontend app (once the pre built UI script has been loaded)
supertokensUIInit("supertokensui", {
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
recipeList: [
supertokensUISession.init({
tokenTransferMethod: "header" // or "cookie"
})
]
});
This change goes in the supertokens-web-js
SDK config at the root of your application:
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 (Optional)important
By returning a fixed value from getTokenTransferMethod
you can strictly control the allowed session types regardless of the frontend config.
You should not set this on the backend if you have more than one client using different modes (for example if you have a website that uses cookie based, and a mobile app that uses header based sessions).
You can provide a getTokenTransferMethod
callback in the configuration of the Session recipe.
- NodeJS
- GoLang
- Python
- Other Frameworks
Important
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).