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
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 configurationimportant
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).