• Stars
    star
    145
  • Rank 254,144 (Top 6 %)
  • Language
    JavaScript
  • Created over 8 years ago
  • Updated about 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Role-based authorization components for React and React-Router

npm version GitHub issues GitHub forks GitHub stars

Role-based authorization for react-router

React-Router Role Authorization is a library which can help you in controlling the access to specific routes depending on given user roles.

This is an implementation of the approach I previously described in my blog post: Role-based authorization using React-Router

Installation

This library is available as a NPM package, so you can install it as you would any other package:

npm install --save-dev react-router-role-authorization

Usage

React-Router Role Authorization library provides two React components: AuthorizedComponent and RoleAwareComponent. Please see below their purpose and how to utilize them in your application.

AuthorizedComponent

Thanks to AuthorizedComponent you can handle access to the route only for specific user roles. To do that, first you have to configure your routes:

ReactDOM.render((
  <Router history={browserHistory}>
    <Route component={AppContainer} path="/">
      <IndexRoute authorize={['user', 'admin']} component={HomeComponent} />
      <Route authorize={['admin']} component={RestrictedContainer}>
        <Route component={RestrictedPageComponent} path="/restricted" />
      </Route>
    </Route>
    <Route component={NotFoundComponent} path="/not-found" />
  </Router>
), document.getElementById('app'));

As you can see, all you have to do is to add the authorize attribute to the main routes of your application. By passing an array of user role names to this attribute, you can define which user roles make this route available.

Additionally you should define a "not found" route which is not restricted by any user role. This will be the place where the user will be redirected to if he will try to access an unavailable route.

The second thing you have to do is to use the AuthorizedComponent. As an example, let's take a look at the sample route configuration above and consider the RestrictedContainer component which is related to the /restricted route path. As you can see it is restricted by the admin user role:

import React from 'react';
import RouteHandler from './RouteHandler';
import { AuthorizedComponent } from 'react-router-role-authorization';
import Cookies from 'js-cookie';

class RestrictedContainer extends AuthorizedComponent {
  constructor(props) {
    super(props);

    this.userRoles = Cookies.get('user').roles;
    this.notAuthorizedPath = '/not-found';
  }

  render() {
    return (
      <div>
        <RouteHandler {...this.props} />
      </div>
    );
  }
}

export default RestrictedContainer;

Ok, so all you have to do to make it work is to inherit the RestrictedContainer component from AuthorizedComponent and set up two properties inside the constructor of the component.

The this.userRoles property should hold an array of user role names (array of strings - e.g. ['admin', 'mod']) which are usually obtained during the authentication process and are usually held in a suitable cookie (Cookies.get('user').roles is only an example - you can handle it however you like but basically it should return an array of user role names).

The this.notAuthorizedPath property is intended to be set to the path name of the route where the user will be redirected in case of no access.

And that's it - from now on, all child routes of the RestrictedContainer component will be restricted by the admin user role.

Custom handling of unauthorized access

By default when a user with insufficient roles tries to access a component he is redirected to notAuthorizedPath defined in AuthorizedComponent. Sometimes you may want to, for example, log it to console etc.

You can achieve it by overriding method handleUnauthorizedRole(routeRoles, userRoles) from AuthorizedComponent.

import React from 'react';
import RouteHandler from './RouteHandler';
import { AuthorizedComponent } from 'react-router-role-authorization';
import Cookies from 'js-cookie';

class RestrictedContainer extends AuthorizedComponent {
  constructor(props) {
    super(props);

    this.userRoles = Cookies.get('user').roles;
    this.notAuthorizedPath = '/not-found';
  }
  
  handleUnauthorizedRole(routeRoles, userRoles){
    // handle unsuccessful authorization somehow
    console.log(`Route is available for roles: ${routeRoles}, but your roles are: ${userRoles}...`);
    
    // you should still redirect somewhere else if you want to prevent from accessing the restricted route ...
    // ... or just use the default behaviour by calling `super.handleUnauthorizedRole()`
    const { router } = this.context;
    router.push('/');
  }

  render() {
    return (
      <div>
        <RouteHandler {...this.props} />
      </div>
    );
  }
}

export default RestrictedContainer;

WARNING! Be careful - if you override the handleUnauthorizedRole method, it will stop redirecting to the notAuthorizedPath path. Instead, it will allow access to the restricted route so you have to prevent it on your own (by redirecting somewhere manually or calling super.handleUnauthorizedRole() to use the default behaviour).

RoleAwareComponent

The RoleAwareComponent component gives you the ability to show or hide the component depending on given user roles.

Its usage is very simple and similar to the AuthorizedComponent component:

import React from 'react';
import { RoleAwareComponent } from 'react-router-role-authorization';
import Cookies from 'js-cookie';

class BoxOne extends RoleAwareComponent {
  constructor(props) {
    super(props);

    this.allowedRoles = ['user'];
    this.userRoles = Cookies.get('user').roles;
  }

  render() {
    const jsx = (
      <div>
        Box One
      </div>
    );

    return this.rolesMatched() ? jsx : null;
  }
}

export default BoxOne;

The BoxOne component inherits from the RoleAwareComponent component. And again, the whole setup is done inside the constructor - this.allowedRoles is an array of user role names which make this component visible; this.userRoles is an array of user role names which the user has.

But this is not all. The component provides two methods: this.rolesMatched and this.rolesMatchedExact which can be used inside the render method of the component:

  • this.rolesMatched finds the intersection of the two arrays and returns true if at least one of the user roles is present among the available roles.
  • this.rolesMatchedExact checks if the available roles array has exactly the same items as the user roles array.

As you can see in the example above, you can use one of these methods to return the markup of the component or just null.

More Repositories

1

react-router-server-side-rendering-example

JavaScript
7
star
2

redux-server-side-rendering-example

JavaScript
5
star
3

react-server-side-rendering-example

JavaScript
4
star
4

CropOnTheFly

A jQuery plugin which allows you to crop images on the fly
JavaScript
4
star
5

polymer-rest-api

The Polymer REST API example application for the blog post purpose.
HTML
4
star
6

polskifrontend-front

Front-end for polskifrontend.pl project
JavaScript
4
star
7

polskifrontend-back

Backend for polskifrontend.pl project
JavaScript
3
star
8

react-ssr-example

Example universal app for the blog post purpose.
JavaScript
3
star
9

polskifrontend-back-v2

JavaScript
2
star
10

react-mobx-example

React + MobX application for the blog post purpose
JavaScript
2
star
11

react-router-v4-example

This repository presents example of the blog post
JavaScript
2
star
12

async-await-example

This repository is made for the blog post purpose.
JavaScript
2
star
13

react-introduction-example

An example React app for the blog post purpose
JavaScript
1
star
14

react-ssr-nextjs

This repository is created for the blog post purposes.
JavaScript
1
star
15

Angular2-Example

Example app of Angular 2
HTML
1
star
16

react-online-training

This repository contains all the excercises for the React online training
HTML
1
star
17

react-higher-order-components-example

This repositore has been created for the blog post purpose.
JavaScript
1
star
18

webpack-2-configuration-example

This repo is made for the blog post purpose.
JavaScript
1
star
19

react-redux-example

React Redux implementation example for the blog post purpose
JavaScript
1
star
20

react-preloader

React component which shows preloader (or whatever you want) until all images are loaded
JavaScript
1
star
21

cats-app-v1

JavaScript
1
star
22

react-redux-rxjs-ajax

This repository is for the blog post purpose
JavaScript
1
star
23

react-mobx-ajax-example

The repository created for the sake of the blog post about mobx and ajax calls.
JavaScript
1
star
24

react-ssr-redux-router-example

This repo is created for the blog post purpose
JavaScript
1
star