3) Protecting routes
caution
- SuperTokens is not yet optimised for 2FA implementation, so you have to add a lot of customisations for it to work. We are working on improving the development experience for 2FA as well as adding more factors like TOPT. Stay tuned.
- A demo app that uses the pre built UI can be found on our GitHub.
We will create a generic wrapper which will protect its child components such that they are viewable only if the user has completed both the auth factors. Otherwise, it will redirect the user to the relevant auth factor screen.
Start by copy / pasting the following code:
import React, { useEffect } from "react";import { SessionAuth, useSessionContext } from "supertokens-auth-react/recipe/session";import { useNavigate } from "react-router-dom";import { SecondFactorClaim } from "./secondFactorClaim";
function ProtectedRoute(props: any) { return ( <SessionAuth> <ProtectedRouteHelper>{props.children}</ProtectedRouteHelper> </SessionAuth> );}
function ProtectedRouteHelper(props: any) { const session = useSessionContext(); const navigate = useNavigate(); const [showUI, setShowUI] = React.useState(false);
useEffect(() => { if (!session.loading) { if (session.invalidClaims.find((a) => a.validatorId === SecondFactorClaim.id)) { // this means that the second factor claim did not pass // so we navigate the user to the second factor screen navigate("/second-factor"); } else { // all claims passed, so we now show the UI to the user. setShowUI(true) } } }, [session, navigate]);
return showUI ? props.children : null;}
Now we can wrap your application routes with the above ProtectedRoute
component:
import React from "react";import { Routes, Route,} from "react-router-dom";import * as reactRouterDom from "react-router-dom";import { SuperTokensWrapper, getSuperTokensRoutesForReactRouterDom } from "supertokens-auth-react";import { SessionAuth } from "supertokens-auth-react/recipe/session";import SecondFactor from "./SecondFactor";import Home from "./Home"
function App() { return ( <SuperTokensWrapper> <div className="App"> <div className="fill"> <Routes> {getSuperTokensRoutesForReactRouterDom(reactRouterDom)} <Route path="/" element={ <ProtectedRoute> <Home /> </ProtectedRoute> } /> <Route path="/second-factor" element={ <SessionAuth> <SecondFactor /> </SessionAuth> } /> </Routes> </div> </div> </SuperTokensWrapper> );}