Implementing user authentication in React with SuperTokens
Tags: javascript, webdev, supertokens, react
Published: 2022-05-12 01:14:19

by [Mercy Ben](https://blog.openreplay.com/authors/mercy-ben)

Have you ever considered implementing easy and safe authentication on your web application at no cost? Have you considered integrating authentication with minimal or no initial environment setup? Then hang on for the next 10 minutes. In this tutorial, you'll learn to Implement user authentication in React with Supertoken. This tutorial is a hands-on demonstration to get you started. Ensure you've met the following requirements:

- You have Node (>= 10.13.0, except for v13) installed
- You have a foundational knowledge of Javascript

To follow along, clone [the code repository for this tutorial](https://github.com/mercicodes/auth-with-supertokens).

## What is Supertokens, and why use it?

Supertokens is a developer-first developer's first, open-source, flexible alternative to Firebase, AWS Cognito, and Auth0. Supertokens allows you to add secure authentication to your web application in minutes with a prebuilt UI that you can easily customize. It has many unique features that make it the best authentication service for your web application.

- **Prebuilt UI**: Supertokens has prebuilt Sign up / sign-in forms (via our front-end SDK) that can be embedded on your website natively.
- **Feature segmentation**: with Supertokens, you can pick only the features you need and see docs relevant to your use case (we call it 'recipes')
- **Simple data model**: Supertokens has a modular structure that allows you to add database tables with fewer configurations.
- **Priced for startups**: Supertokend has a generous limit and pricing for our managed service, and it's free forever for self-hosted.
- **Integrate with any service**:  You can set up your content delivery service (e.g., SMS or email) for free.

## Scaffold React Project

To get started, we'll create a React application with the command below:

```
npm create-react-app auth-with-supertokens
```

The command will scaffold a new project for us with the following folder structure below:

```
auth-with-supertokens
 ┣ node_modules
 ┣ public
 ┣ src
 ┃ ┣ App.css
 ┃ ┣ App.js
 ┃ ┣ App.test.js
 ┃ ┣ index.css
 ┃ ┣ index.js
 ┃ ┣ logo.svg
 ┃ ┣ reportWebVitals.js
 ┃ ┗ setupTests.js
 ┣ .gitignore
 ┣ README.md
 ┣ package-lock.json
 ┗ package.json
```

## Configure the front-end SDK
With our React project created, let's set up the SuperTokens front-end SDK. First, we need to install the SuperTokens React SDK:

```
npm i -s supertokens-auth-react
```

Next, call the `init` function in your `App.js` file:

```javascript
import React from "react";

import SuperTokens from "supertokens-auth-react";
import EmailPassword from "supertokens-auth-react/recipe/emailpassword";
import Session from "supertokens-auth-react/recipe/session";

SuperTokens.init({
  appInfo: {
    // learn more about this on https://supertokens.com/docs/emailpassword/appinfo
    appName: "auth-application",
    apiDomain: "http://localhost:3001",
    websiteDomain: "http://localhost:3000",
    apiBasePath: "/api/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [EmailPassword.init(), Session.init()],
});

/* Your App */
class App extends React.Component {
  render() {
    return <div>{/*Your app components*/}</div>;
  }
}
```

In the code above, we initialized the SuperTokens SDK using the `init` method, which takes the following objects as required parameters in the `appInfo` object:

- `appName`: This is the name of your application. It is used when sending password reset or email verification emails
- `apiDomain`: This is the domain part of your website, where the login UI will be shown.
- `websiteDomain`: This is the domain part of your API endpoint that the front end talks to.
- `apiBasePath`: The default path where the front end SDK will query.
- `websiteBasePath`: This is the default path where the website UI will be displayed.

**Note:** Ensure that `apiDomain` and `websiteDomain` match the host for your back end and front end.

SuperTokens has a lot of [recipe](https://supertokens.com/docs/guides), but for this tutorial, we'll use the `EmailPassword` as specified in the `recipeList` array.

## Create App Components

With the Supertokens SDK setup, let's create our component. First, create a component folder inside the `src` directory and a `BookStore` component within. Now add the code below to the `BookStore` component.

```javascript
export default function BookStore() {
  const BookList = [
    {
      SID: 1,
      name: "Python for Beginners",
      author: "Mercy Ben",
      coppies: 10,
      publishedAt: "2022-04-03",
    },
    {
      SID: 2,
      name: "Python for Dummies",
      author: "Nelson Fos",
      coppies: 20,
      publishedAt: "2022-01-03",
    },
    {
      SID: 3,
      name: "Blockchain master course",
      author: "Gilt John",
      coppies: 12,
      publishedAt: "2022-03-03",
    },
  ];

  return (
    <div className="book">
      <ul>
        {BookList.map((book) => (
          <li>{book.name}</li>
        ))}
      </ul>
    </div>
  );
}
```

In the code above, we created a `BookList` array with some dummy data, then used the map function to loop through them and render them to the browser. (In real apps, we'd get the list from the server, but that doesn't matter here; we want to deal with authentication only.) Next, create a `Header` component and add the code below. 

```javascript
export default function Header() {
  return (
    <div className="header">
      <ul>
        <li>Home</li>
        <li className="logout">Logout</li>
      </ul>
    </div>
  );
}
```

Here we created a central header where we can navigate between the `BookStore`, `Login UI`, and the `Logout` component. Delete the styles in the `App.css` file and add the following styles below:

```
* {
  padding: 0px;
  margin: 0px;
}

.header {
  background-color: rgb(218, 218, 218);
  padding: 10px;
  color: #212529;
}

.header ul {
  display: flex;
  justify-content: space-between;
  list-style: none;
  align-items: center;
}

.header ul .logout {
  background-color: #dc3545;
  border-color: #dc3545;
  display: inline-block;
  font-weight: 400;
  line-height: 1.5;
  color: white;
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  cursor: pointer;
  border: 1px solid transparent;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  border-radius: 0.25rem;
}

.book ul li {
  padding: 10px;
  background-color: #212529;
  color: white;
  margin-bottom: 10px;
  margin: 10px;
}
```

Finally, import `BookStore`, `Header`, and the `App.css` file in the `App` component.

```javascript
// ...

import BookStore from "./component/BookStore";
import Header from "./component/Header";
import "./App.css";

//...

/* Your App */
export default function App() {
  return (
    <div>
      <Header />
      <BookStore />
    </div>
  );
}
```

If you navigate to [localhost:3000](http://localhost:3000/) 0n your browser, you will see the output shown on the screenshot below:

![Book store page](https://blog.openreplay.com/static/9502f26d27c63bc9d017e2cefcf5f05b/5eb1c/image01.png)


## Open Source Session Replay

_[OpenReplay](https://github.com/openreplay/openreplay) is an open-source alternative to FullStory and LogRocket. It gives you full observability by replaying everything your users do on your app and showing how your stack behaves for every issue. OpenReplay is self-hosted for full control over your data._

![replayer.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1647097041609/Qi6sMOaaB.png)

_Happy debugging for modern frontend teams - [start monitoring your web app for free](https://github.com/openreplay/openreplay)._



## Setup the login UI

Now let's set up the SuperTokens login UI. But before that, you need to install `react-router-dom` to enable you to create the routes for the application. So, run the command below on your terminal.

```
npm i react-router-dom
```

**Note:** Ensure the version you are installing is at least version 16.* Next, Call the `getSuperTokensRoutesForReactRouterDom` method from within any `react-router-dom` Routes component in `App.js`.

```javascript
// ...

import SuperTokens, {
  getSuperTokensRoutesForReactRouterDom,
} from "supertokens-auth-react";
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import * as reactRouterDom from "react-router-dom";

// ...

/* Your App */
export default function App() {
  return (
    <div>
      <Header />
      <BrowserRouter>
        <Routes>
          {/*This renders the login UI on the /auth route*/}
          {getSuperTokensRoutesForReactRouterDom(reactRouterDom)}
          {/*Your app routes*/}
          <Route path="/" element={<BookStore />} />
        </Routes>
      </BrowserRouter>
    </div>
  );
}
```

We have set up the routes for the application. The `Header` component will be accessible from the login and `BookStore` components. So if you go back to your browser and navigate to `/auth,` you will see the login UI recipe setup for you by SuperTokens as shown below:

![login UI](https://blog.openreplay.com/static/1520ae85d9c6c931207a8a2f80afdc75/ad3a2/image02.png)

You can also navigate the signup route by clicking the `sign up` link.

![signup UI](https://blog.openreplay.com/static/d0e1a805d3f07a6bcd9aa2f4955602d2/32536/image03.png)

## Protect Routes

Now we have set up the login UI for our application. But the users can view the bookstore without being authenticated. To prevent that, let's protect the `BookStore` route. First, update the `BookStore` route:

```javascript
<Route
  path="/"
  element={
    <EmailPassword.EmailPasswordAuth
      onSessionExpired={() => {
        alert("Session expired!");
      }}
    >
      <BookStore />
    </EmailPassword.EmailPasswordAuth>
  }
/>
```

If a user tries to access the `/` route, they will be automatically redirected to the `/auth` route by SuperTokens.

## Setup the backend SDK

For the SuperTokens front-end SDK to work, it needs to talk to the back-end SDK. You can choose to use any framework for your back end. But for the demonstration in this tutorial, we'll use Node.js Express SDK. So let's set that up pretty quick. 

Create a new folder outside the `auth-with-supertokens` directory called `backend-sdk.` Then, initialize a Node.js project and install the SuperTokens Node.js SDK, Express, and Cors by running the command below on your terminal.

```
npm init -y && npm i -s supertokens-node express cors
```

Create an `index.js` file and add the code below:

```javascript
const express = require("express");
const supertokens = require("supertokens-node");
const Session = require("supertokens-node/recipe/session");
const EmailPassword = require("supertokens-node/recipe/emailpassword");

const app = express();

supertokens.init({
  framework: "express",
  supertokens: {
    // try.supertokens.com is for demo purposes. Replace this with the 
    // address of your core instance (sign up on supertokens.com), or self host a core.
    connectionURI: "https://try.supertokens.com",
    // apiKey: "IF YOU HAVE AN API KEY FOR THE CORE, ADD IT HERE",
  },
  appInfo: {
    // learn more about this on https://supertokens.com/docs/session/appinfo
    appName: "auth-application",
    apiDomain: "http://localhost:3001",
    websiteDomain: "http://localhost:3000",
    apiBasePath: "/api/auth",
    websiteBasePath: "/auth",
  },
  recipeList: [
    EmailPassword.init(), // initializes signin / sign up features
    Session.init(), // initializes session features
  ],
});

const PORT = 3001;
app.listen(PORT, () => console.log(`Server runing on port ${PORT}`));
```

In the above code, we initialized SuperTokens. Then, we provided the details of our application as we did in the front end in the `appInfo` object and created an express server.

Note: SuperTokens have a hosted database to store records for your demo project. You can also set up and connect to your own [Core](https://supertokens.com/docs/emailpassword/quick-setup/core/) self-hosted database.

Now run the Express server with the command below:

```
npm index.js
```

If you inspect the application, you should see some CORS warnings. Let's fix those.

## Enable CORS

To allow our front end to communicate with the back end, we need to enable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS).

```javascript
// ...

const cors = require("cors");
const { middleware } = require("supertokens-node/framework/express");

// ...

// ...other middlewares
app.use(
  cors({
    origin: "http://localhost:3001",
    allowedHeaders: ["content-type", ...supertokens.getAllCORSHeaders()],
    credentials: true,
  })
);

app.use(middleware());

// ...your API routes
```

The CORS errors should disappear now. So go ahead and sign up to test things out.
    
Once you signup or sign in, SuperTokens will create and store your session data on your browser, which can expire and become invalid. 

![Session data](https://blog.openreplay.com/static/f745e71da473b99b373165e47c717deb/1729a/image04.png)

Also, as far as your session remains valid, you can't navigate to the `/auth` route unless you clear your session by logging out.

## Logout Users 

Now let's implement the logout route. First, create a logout method in the `App` component and pass it as props to the `Header` component.
    
```javascript
// ...

import EmailPassword, {
  signOut,
} from "supertokens-auth-react/recipe/emailpassword";

// ...

async function onLogout() {
  await signOut();
  window.location.href = "/";
}

//  ...
```

In the above code, we imported and used the signOut function provided by SuperTokens to log out a user.

Finally, update the Header component.

```javascript
export default function Header(props) {
  const { onLogout } = props;
  return (
    <div className="header">
      <ul>
        <li>Home</li>
        <li className="logout" onClick={onLogout}>
          Logout
        </li>
      </ul>
    </div>
  );
}
```

Here we destructure our `props` object to get the `onLogout` function and bind it to an `onClick` event on the logout button.

## Conclusion

Congrats! You made it at this point. You've learned how to easy and fast it is to implement user authentication in React with SuperTokens. We started with an introduction to SuperTokens and why a developer should use it. Then we moved to create a BookStore application for demonstration. Now which auth service will you prefer to use in your next project? Feel free to learn more about SuperTokens from the [official documentation](https://supertokens.com/).

[![newsletter](https://blog.openreplay.com/static/e6b18eda7a327511296a2f27692f9c70/e9957/newsletter.png)](https://newsletter.openreplay.com/)