Skip to main content
Which frontend SDK do you use?
supertokens-web-js / mobile
supertokens-auth-react

5b. Session verification in getServerSideProps

note

This is applicable for when verifying a session in getServerSideProps or getInitialProps.

For this guide, we will assume that we want to pass the logged in user's ID as a prop to a protected route. An easier method to achieve this would be to directly get the user ID from the frontend, but for this example, we will pass it from the server side.

1) We use getSession in getServerSideProps#

important

If using getInitialProps, the method described below applies as well. The only difference is the way the props are returned (see comments in the code).

An example of this can be found here.

import Session from 'supertokens-node/recipe/session'
import supertokensNode from 'supertokens-node'
import { backendConfig } from '../config/backendConfig'

export async function getServerSideProps(context: any) {

// this runs on the backend, so we must call init on supertokens-node SDK
supertokensNode.init(backendConfig())

// this will contain the session object post verification
let session

try {
// getSession will do session verification for us
session = await Session.getSession(context.req, context.res, {
overrideGlobalClaimValidators: () => {
// this makes it so that no custom session claims are checked
return []
}})
} catch (err: any) {
if (err.type === Session.Error.TRY_REFRESH_TOKEN) {

// in this case, the session is still valid, only the access token has expired.
// The refresh token is not sent to this route as it's tied to the /api/auth/session/refresh API paths.
// So we must send a "signal" to the frontend which will then call the
// refresh API and reload the page.

return { props: { fromSupertokens: 'needs-refresh' } }
// or return {fromSupertokens: 'needs-refresh'} in case of getInitialProps
} else if (err.type === Session.Error.UNAUTHORISED) {
// in this case, there is no session, or it has been revoked on the backend.
// either way, sending this response will make the frontend try and refresh
// which will fail and redirect the user to the login screen.
return { props: { fromSupertokens: 'needs-refresh' } }
}

throw err
}

// session verification is successful and we can pass
// the user's ID to the frontend.

return {
props: { userId: session!.getUserId() },
}
// or return {userId: session.getUserId()} in case of getInitialProps
}
caution

Do not use the verifySession function here. The reason is that this will send a reply to the client in case of TRY_REFRESH_TOKEN, and here, we want to catch that error and send a custom reply.

2) Doing manual refresh on the frontend#

  • The following will refresh a session if needed, for all your website pages
  • This goes in the /pages/_app.tsx file
  • An example of this can be found here.
/pages/_app.tsx
import React, { useEffect } from "react";
import Session from 'supertokens-auth-react/recipe/session'
import { redirectToAuth } from 'supertokens-auth-react'
import { AppProps } from "next/app";

function MyApp({ Component, pageProps }: AppProps<{fromSupertokens: string}>) {
useEffect(() => {

async function doRefresh() {
// pageProps.fromSupertokens === 'needs-refresh' will be true
// when in getServerSideProps, getSession throws a TRY_REFRESH_TOKEN
// error.

if (pageProps.fromSupertokens === 'needs-refresh') {
if (await Session.attemptRefreshingSession()) {
// post session refreshing, we reload the page. This will
// send the new access token to the server, and then
// getServerSideProps will succeed
location.reload()
} else {
// the user's session has expired. So we redirect
// them to the login page
redirectToAuth()
}
}
}
doRefresh()

}, [pageProps.fromSupertokens])

if (pageProps.fromSupertokens === 'needs-refresh') {
// in case the frontend needs to refresh, we show nothing.
// Alternatively, you can show a spinner.

return null
}

// the below is already there by default
return <Component {...pageProps} />
}

export default MyApp

3) Consume the userId returned by getServerSideProps in your component#

On success, getServerSideProps returns

{
// Refer to Step 1)
props: { userId: session.getUserId() }
}

Therefore, the associated page can access the userId like:

export default function Home(props: any) {
let userId = props.userId;
}