React Authorization

Sample Project

Download this sample project configured with your Auth0 API Keys.

System Requirements
  • React 15.3
Show requirements

Many identity providers will supply access claims (such as roles or groups) with the user. You can request these in the token by setting scope: openid roles or scope: openid groups. However, not every identity provider supplies this type of information. Fortunately, Auth0 has an alternative, which is to create a rule for assigning different roles to different users.

NOTE: This tutorial assumes that you have already completed the rules tutorial and that you know how to implement a basic rule in your app.

Create a Rule to Assign Roles

First, create a rule that assigns users to either an admin role or a single user role. Go to the New Rule page in the Auth0 dashboard and select the Set Roles to a User template under Access Control.

By default, this rule will assign the user an admin role if the user’s email contains @example.com. Otherwise, the user will be assigned a regular user role.

You can modify this line in the default script to change the domain name to one suitable for your setup:

if (user.email.indexOf('@example.com') > -1)

NOTE: You can set roles other than admin and user and you may customize the rule as needed.

Check if a User's Role is Present

After creating the new rule, update the AuthService helper class with a new isAdmin method. This method will be useful in other parts of your application. It returns true for admin users and false otherwise.

Included this snippet in the AuthService.js file:

// src/utils/AuthService.js

export default class AuthService extends EventEmitter {
  // ...
  isAdmin() {
    // Checks if user have `admin` role in his profile app_metadata
    const profile = this.getProfile();
    const { roles } = profile.app_metadata || {};
    return !!roles && roles.indexOf('admin') > -1;
  }
}

3. Restrict a Route based on User's Roles

To demonstrate how to restrict access to certain routes based on a user's roles, you can update the routes.js file as shown below.

The new /admin route requires the current user to have an admin role, and redirects to /unauthorized if auth.isAdmin() returns false.

Here is the complete routes.js code:

// src/views/Main/routes.js

import React from 'react'
import {Route, IndexRedirect, Link} from 'react-router'
import AuthService from 'utils/AuthService'
import Container from './Container'
import Home from './Home/Home'
import Login from './Login/Login'
import Admin from './Admin/Admin'
import Unauthorized from './Unauthorized/Unauthorized'

// initializing the AuthService instance
const auth = new AuthService('YOUR_CLIENT_ID', 'YOUR_AUTH0_DOMAIN');
// redirecting to saved url after a successful login
const redirectAfterLogin = (replace) => {
  const url = localStorage.getItem('redirect_after_login')
  if (url) {
    localStorage.removeItem('redirect_after_login')
    replace({ pathname: url })
  }
}
// onEnter callback to validate authentication in private routes
const requireAuth = (nextState, replace) => {
  if (!auth.loggedIn()) {
    // saving the current url to redirect later
    localStorage.setItem('redirect_after_login', nextState.location.pathname)
    replace({ pathname: '/login' })
  } else {
    redirectAfterLogin(replace)
  }
}
// onEnter callback to require admin role
const requireAdminAuth = (nextState, replace) => {
  if (!auth.isAdmin()) {
    replace({ pathname: '/unauthorized' })
  }
}

export const makeMainRoutes = () => {
  return (
    <Route path="/" component={Container} auth={auth}>
      <IndexRedirect to="/home" />
      <Route onEnter={requireAuth}> // all nested routes require authentication
        <Route path="home" component={Home} />
        // only /admin route required also 'admin' role
        <Route path="admin" component={Admin} onEnter={requireAdminAuth} />
        <Route path="unauthorized" component={Unauthorized} />
      </Route>
      <Route path="login" component={Login} />
    </Route>
  )
}

export default makeMainRoutes

Note: The client ID and domain for your application are passed to the AuthService in the above snippet, but the downloadable samples contain a .env.example file that should be renamed to .env and populated with these values.

Another feature introduced in the above code is correct redirection after a successful login. Now the current URL is stored as a local storage item before the user is directed to the login page. Later, the value is retrieved in the redirectAfterLogin method.

Admin and Unauthorized Views

As a final step, add View Components for the two new routes: Admin and Unauthorized as shown below:

// src/views/Main/Admin/Admin.js

import React from 'react'
import {Link} from 'react-router'

export class Admin extends React.Component {
  render() {
    return (
      <div>
        <h2>Admin</h2>
        <p>You are viewing this because you are logged in and you have 'admin' role</p>
        <Link to={'/home'}>Back to Home</Link>
      </div>
    )
  }
}

export default Admin;
// src/views/Main/Unauthorized/Unauthorized.js

import React from 'react'
import {Link} from 'react-router'

export class Unauthorized extends React.Component {
  render() {
    return (
      <div>
        <h2>Unauthorized: you are not allowed to see this content</h2>
        <Link to={'/home'}>Back to Home</Link>
      </div>
    )
  }
}

export default Unauthorized;

Now you can verify that only users logged in with an email that contains @example (or whichever criteria is enforced by the rule you create) will be able to access the /admin route.

Previous Tutorial
7. Rules
Next Tutorial
9. Calling APIs
Use Auth0 for FREECreate free Account