Skip to content
Esc
navigateopen⌘Jpreview
Dashboard
On this page

Protect frontend routes

Protect frontend routes by requiring user sessions and verifying session claims for access control.

Protect frontend routes by requiring user sessions and verifying session claims for access control.

Before you start



UI type

Protect a route

You can wrap your components with the <SessionAuth> react component. This ensures that your component renders only if the user has logged in. If they are not logged in, the user gets redirected to the login page.

You can use the doesSessionExist function to check if a session exists in all your routes.

import React from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { SuperTokensWrapper } from "supertokens-auth-react";
import { SessionAuth } from "supertokens-auth-react/recipe/session";
import MyDashboardComponent from "./dashboard";

class App extends React.Component {
  render() {
    return (
      <SuperTokensWrapper>
        <BrowserRouter>
          <Routes>
            <Route
              path="/dashboard"
              element={
                <SessionAuth>
                  {/*Components that require to be protected by authentication*/}
                  <MyDashboardComponent />
                </SessionAuth>
              }
            />
          </Routes>
        </BrowserRouter>
      </SuperTokensWrapper>
    );
  }
}
import Session from "supertokens-web-js/recipe/session";

async function doesSessionExist() {
  if (await Session.doesSessionExist()) {
    // user is logged in
  } else {
    // user has not logged in yet
  }
}

Optional session requirement

You can provide the requireAuth={false} prop when using <SessionAuth> as shown below:

Check the claims of a session

Sometimes, you may also want to check if there are certain claims in the session before granting access to a route. For example, you may want to check that the session has the admin role claim for certain APIs, or that the user has completed 2FA.

You can achieve this using the session claims validator feature. Let’s take an example of using the user roles claim to check if the session has the admin claim:

import React from "react";
import { SessionAuth } from "supertokens-auth-react/recipe/session";
import { AccessDeniedScreen } from "supertokens-auth-react/recipe/session/prebuiltui";
import { UserRoleClaim /*PermissionClaim*/ } from "supertokens-auth-react/recipe/userroles";

const AdminRoute = (props: React.PropsWithChildren<any>) => {
  return (
    <SessionAuth
      accessDeniedScreen={AccessDeniedScreen}
      overrideGlobalClaimValidators={(globalValidators) => [
        ...globalValidators,
        UserRoleClaim.validators.includes("admin"),
      ]}
    >
      {props.children}
    </SessionAuth>
  );
};
import Session from "supertokens-web-js/recipe/session";
import { UserRoleClaim /*PermissionClaim*/ } from "supertokens-web-js/recipe/userroles";

async function shouldLoadRoute(): Promise<boolean> {
  if (await Session.doesSessionExist()) {
    let validationErrors = await Session.validateClaims({
      overrideGlobalClaimValidators: (globalValidators) => [
        ...globalValidators,
        UserRoleClaim.validators.includes("admin"),
        /* PermissionClaim.validators.includes("modify") */
      ],
    });

    if (validationErrors.length === 0) {
      // user is an admin
      return true;
    }

    for (const err of validationErrors) {
      if (err.id === UserRoleClaim.id) {
        // user roles claim check failed
      } else {
        // some other claim check failed (from the global validators list)
      }
    }
  }
  // either a session does not exist, or one of the validators failed.
  // so we do not allow access to this page.
  return false;
}

Above, you create a generic component called AdminRoute, which enforces that its child components render only if the user has the admin role. In the AdminRoute component, the SessionAuth wrapper ensures that the session exists. The UserRoleClaim validator is also added to the <SessionAuth> component, which checks if the validators pass or not. If all validation passes, the props.children component renders. If the claim validation has failed, it displays the AccessDeniedScreen component instead of rendering the children. You can also pass your own custom component to the accessDeniedScreen prop.

If you want to have more complex access control, you can get the roles list from the session as follows, and check the list yourself:

  • We call the validateClaims function with the UserRoleClaim validator which makes sure that the user has an admin role.
  • The globalValidators represents other validators that apply to all calls to the validateClaims function. This may include a validator that enforces that you have verified the user’s email (if enabled by you).
  • We can also add a PermissionClaim validator to enforce a permission.

If you want to have more complex access control, you can get the roles list from the session as follows, and check the list yourself:


See also

API reference

API schema and response details