Skip to main content

Using Warrant with React

The Warrant React SDK allows you to easily perform access control checks directly in your React application so you can show & hide pages, components, and other content that requires privileged access. The library interacts directly with the Warrant API using short-lived session tokens that must be created server-side using your API key. Refer to our guide on Creating Session Tokens to learn how to generate session tokens you can pass to the Warrant React SDK to start performing client-side access checks.

The following guide assumes that you already have a Warrant account and corresponding API and Client keys. If you don't already have an account, you can sign up for one here.

Install the Warrant React SDK#

Run the following command in your project directory to install the Warrant React SDK:

npm install @warrantdev/react-warrant-js

Configure WarrantProvider#

The Warrant React SDK uses React Context to allow you to access utility methods for performing access checks anywhere in your app. Wrap your application with WarrantProvider, passing it your Client Key using the clientKey prop.

// App.jsximport React from "react";import { WarrantProvider } from "@warrantdev/react-warrant-js";
const App = () => {    return <WarrantProvider clientKey="client_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=">        {/* Routes, ThemeProviders, etc. */}    </WarrantProvider>;};
export default App;

Set the Session Token#

To finish initializing the Warrant SDK you must use the setSessionToken method to give the SDK a valid session token to make access check requests to the Warrant API with. Refer to our guide on Creating Session Tokens to learn how to generate session tokens. We recommend generating a session token for the user during your authentication flow. You can then return the token to the client and use it to initialize the SDK. Here's an example of what that might look like:

// Login.jsximport React from "react";import { useWarrant } from "@warrantdev/react-warrant-js";
const Login = () => {    const { setSessionToken } = useWarrant();
    const loginUser = async (event) => {        const response = await login(email, password);
        // NOTE: This session token must be generated        // server-side when logging users into your        // application and then passed to the client.        // Access check calls in this library will fail        // if the session token is invalid or not set.        setSessionToken(response.warrantSessionToken);
        //        // Redirect user to logged in page        //    };
    return <form onSubmit={loginUser}>        {/* email & password inputs, etc. */}    </form>;};
export default Login;

Protect Routes#

withWarrant#

withWarrant is a Higher Order Component (HOC) that can be wrapped around routes and components that should only be accessible to users who have access. Given an objectType, objectId, and relation, the HOC will automatically perform an access check and only render the wrapped component if the user has access.

Use withWarrant to add protected routes to your application like so:

// App.jsximport React from "react";import { Router, Route, Switch } from "react-router-dom";import { createBrowserHistory } from "history";import { WarrantProvider, withWarrant } from "@warrantdev/react-warrant-js";
const history = createBrowserHistory();
const App = () => {    return <WarrantProvider clientKey="client_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=">        <Router history={history}>            <Switch>                <Route path="/public_route" exact component={PublicPage}/>                {/*                    Only render ProtectedPage if the user                    is a "viewer" of the route "protected_route".                */}                <Route path="/protected_route" exact component={withWarrant(ProtectedPage, {                    objectType: "route",                    objectId: "protected_route",                    relation: "viewer",                    redirectTo: "/public_route",                })}>            </Switch>        </Router>    </WarrantProvider>;};
export default App;

NOTE: The above example uses react-router but you can use any routing library with the Warrant React SDK.

ProtectedRoute#

If you're using react-router to manage routing in your app, you can make use of the ProtectedRoute component instead of withWarrant to protect your routes.

import React from "react";import { Router, Route, Switch } from "react-router-dom";import { createBrowserHistory } from "history";import { WarrantProvider, ProtectedRoute } from "@warrantdev/react-warrant-js";import PublicPage from "./PublicPage";import ProtectedPage from "./ProtectedPage";
const history = createBrowserHistory();
const App = () => {    return <WarrantProvider clientKey="client_test_f5dsKVeYnVSLHGje44zAygqgqXiLJBICbFzCiAg1E=">        <Router history={history}>            <Switch>                <Route path="/public_route" exact component={PublicPage}/>                <ProtectedRoute                    path="/protected_route/:id"                    key="/protected_route/:id"                    exact                    component={ProtectedPage}                    options={{                        objectType: "myObject",                        objectIdParam: "id",                        relation: "viewer",                        redirectTo: "/public_route",                    }}                />            </Switch>        </Router>    </WarrantProvider>;};
export default App;

Add Access Checks in Components#

Sometimes a page or component should be visible to all users, but not all of its functionality should be. ProtectedComponent and hasWarrant are a component and a utility method that allow you to add more granular access checks within components.

hasWarrant#

Make specific access checks within a component using hasWarrant:

import React, { useEffect } from "react";import { useWarrant } from "@warrantdev/react-warrant-js";
const MyComponent = () => {    const { hasWarrant } = useWarrant();
    useEffect(() => {        const fetchProtectedInfo = async () => {            // Only fetch protected info from server if            // user is a "viewer" of the info object "protected_info".            if (await hasWarrant("info", "protected_info", "viewer")) {                // request protected info from server            }        };
        fetchProtectedInfo();    });
    return <div>        {protectedInfo &&            <ProtectedInfo>{protectedInfo}</ProtectedInfo>        }    </div>;};
export default MyComponent;

ProtectedComponent#

Wrap components in ProtectedComponent to only render them if the user has the required access:

import React from "react";import { ProtectedComponent } from "@warrantdev/react-warrant-js";
const MyComponent = () => {    return <div>        <MyPublicComponent/>        {/* hides MyProtectedComponent unless the user is a "viewer" of myObject with id object.id */}        <ProtectedComponent            objectType="myObject"            objectId={object.id}            relation="viewer"        >            <MyProtectedComponent/>        </ProtectedComponent>    </div>;};
export default MyComponent;