Session verification during server side rendering
Overview
In Server Side Rendering (SSR) scenarios, the session verification process is slightly different. Check the following guide to understand how to adjust the flow to work with SSR.
Before you start
Getting access to the session during server side rendering is only possible using cookie-based sessions. This is the default setting, but you have to keep this in mind if you want to switch to header-based sessions.
This guide only applies to scenarios which involve SuperTokens Session Access Tokens.
Steps
1. Enable sharing of cookies across sub domains
If your API layer and website are on different sub domains (like example.com
and api.example.com
), then by default, the session tokens attach only to api.example.com
.
Change this to ensure that the session tokens attach to .example.com
and the access token cookie goes to your web server on example.com
.
Enable this by setting the cookieDomain
configuration on the backend.
2. Do JWT verification
Follow the JWT verification guide to verify the JWT on the server side.
You can read the JWT from the sAccessToken
cookie in the request object.
If the JWT is missing, invalid, or expired, redirect the user to a /refresh-session?redirectBack=<current route>
page. You can have any path for this since it's your website.
On the /refresh-session
page, you want to call the attemptRefreshingSession
function (from the client side).
This function attempts to refresh the session.
If it succeeds, it returns true
.
If it fails, it returns false
.
If it returns true
, you want to redirect the user back to the page they were on.
If it returns false
, you want to redirect the user to the login page.
3. Implement the refresh session flow (/refresh-session
page)
On this path, attempt refreshing the session which can yield:
- Success: The frontend gets new access and refresh tokens.
Post this, redirect the user to the path mentioned on the
redirectBack
query parameter. - Failure: This would happen if the session has expired or the backend has revoked it. Either way, you want to redirect the user to the login page.
Below is the code snippet that you can use on the /refresh-session
path on the frontend
What type of UI are you using?
import React from "react";
import Session from "supertokens-auth-react/recipe/session"
import SuperTokens from "supertokens-auth-react";
export function AttemptRefresh(props: any) {
React.useEffect(() => {
let cancel = false;
Session.attemptRefreshingSession().then(success => {
if (cancel) {
// component has unmounted somehow..
return;
}
if (success) {
// we have new session tokens, so we redirect the user back
// to where they were.
const urlParams = new URLSearchParams(window.location.search);
window.location.href = urlParams.get('redirectBack')!;
} else {
// we redirect to the login page since the user
// is now logged out
SuperTokens.redirectToAuth();
}
})
return () => {
cancel = true;
}
}, []);
return null;
}
Why trigger the refresh session flow instead of redirecting the user to the login page directly?
Two reasons why JWT verification can fail are:
- The session tokens were not passed from the frontend: This can happen if the route is accessed when the user has logged out.
- The session tokens pass from the frontend, but the JWT has expired.
If the user goes to the login page directly, then in the second case, the frontend redirects the user back to the current route (since the refresh token is still valid), causing an infinite loop. To counteract this issue, redirect the user to a refresh page, which creates a new access token. In the first case, when the user is actually logged out, the refreshing fails, and they go to the login page anyway.
Can verifySession
or getSession
replace manual JWT verification?
Yes, you can, but it is not recommended because:
- Often the web server is on a different process than the API server. Using the backend SDK requires you to give it the credentials to the SuperTokens core, which you might not want to provide to the web server.
- The
session
object resulting fromverifySession
andgetSession
makes it easy to mutate the access token payload. These mutations reflect on the frontend via network interceptors from the frontend SDK. In SSR, the browser makes the call to your web server directly, and the frontend SDK interceptors don't run. This can cause inconsistency between the access token payload as seen on the frontend vs the backend.