Skip to content
Esc
navigateopen⌘Jpreview
Dashboard
On this page

5b. Session verification in getServerSideProps

Verify user sessions in Next.js using `getServerSideProps` for secure route access.

For this guide, we will assume that we want to pass the logged in user’s ID as a prop to a protected route.

1. Check the session in getServerSideProps

import type { GetServerSidePropsContext } from "next";
import { getSSRSession } from "supertokens-node/nextjs";

export function createGetServerSideProps(ensureSuperTokensInit: () => void) {
  return async function getServerSideProps(context: GetServerSidePropsContext) {
    ensureSuperTokensInit();
    const cookies = Object.entries(context.req.cookies).flatMap(([name, value]) =>
      value === undefined ? [] : [{ name, value }],
    );
    const { accessTokenPayload, error } = await getSSRSession(cookies);

    if (error) {
      throw error;
    }

    if (accessTokenPayload === undefined) {
      // This occurs if the token has expired or doesn't exist.
      // Either way, sending this response prompts the frontend to attempt a session refresh.
      //
      // Case 1: Token doesn't exist
      // - The refresh will fail, and the user will be redirected to the login page.
      //
      // Case 2: Token has expired
      // - The client will call the refresh API and update the session tokens.

      return { props: { fromSupertokens: "needs-refresh" } };
      // or return {fromSupertokens: 'needs-refresh'} in case of getInitialProps
    }

    return {
      props: { userId: accessTokenPayload.sub },
    };

    // or return { userId: accessTokenPayload.sub } in case of getInitialProps
  };
}

In your page module, import ensureSuperTokensInit from your application’s backend configuration and export getServerSideProps = createGetServerSideProps(ensureSuperTokensInit). This keeps session verification connected to the same SDK configuration as your authentication routes.

2. Doing manual refresh on the frontend

UI type
  • The following will refresh a session if needed, for all your website pages
  • This goes in the /pages/_app.tsx file
import { useEffect, useState } from "react";
import Session from "supertokens-auth-react/recipe/session";
import { redirectToAuth } from "supertokens-auth-react";
import type { AppProps } from "next/app";

function MyApp({ Component, pageProps }: AppProps<{ fromSupertokens: string }>) {
  const [didError, setDidError] = useState(false);

  useEffect(() => {
    async function doRefresh() {
      try {
        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
          await redirectToAuth();
        }
      } catch {
        setDidError(true);
      }
    }

    if (pageProps.fromSupertokens === "needs-refresh") {
      void doRefresh();
    }
  }, [pageProps.fromSupertokens]);

  if (didError) {
    return <p role="alert">Unable to refresh your session. Please reload the page.</p>;
  }

  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: accessTokenPayload.sub,
  },
}

Therefore, the associated page can access the userId like:

interface HomeProps {
  userId: string;
}

export default function Home({ userId }: HomeProps) {
  return <p>Your user ID is: {userId}</p>;
}

API reference

API schema and response details