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
Important
supertokens-auth-react SDK and will inject the React components to show the UI. Therefore, the code snippet below refers to the supertokens-auth-react SDK.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-auth-react SDK and will inject the React components to show the UI. Therefore, the code snippet below refers to the supertokens-auth-react SDK.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-auth-react";
import Session from "supertokens-auth-react/recipe/session";
SuperTokens.init({
appInfo: {
apiDomain: "...",
appName: "...",
websiteDomain: "..."
},
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).