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