Skip to main content

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).
  • We do NOT need to call supertokens.init here since this is not an API route, and we already call it in _app.js

An example of this can be found here.

import Session from 'supertokens-node/recipe/session'
export async function getServerSideProps(context) {
    // 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)    } catch (err) {        if (err.type === Session.Error.TRY_REFRESH_TOKEN) {                        // in this case, the session is still valid, only the refresh 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) {
            // user is logged out. Since this is for a protected route,            // we can simple send an empty prop object. Alternatively,            // you can pass anything else you would like here.            return { props: {} }            // or return {} in case of getInitialProps        } else {            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.js file
  • An example of this can be found here.
/pages/_app.js
import Session from 'supertokens-auth-react/recipe/session'import { redirectToAuth } from 'supertokens-auth-react/recipe/emailpassword'
function MyApp({ Component, pageProps }) {    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

{    props: { userId: session.getUserId() }}

Therefore, the associated page can access the userId like:

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