Using react router to implement front end route authentication

Time:2021-1-26

React-RouterIt is a very important part of react ecology. Now, the routing of single page application of react is basically managed by the front-end itself, instead of the back-end routing in the past. The common routing Library of react isReact-Router. This article wants to write about itReact-RouterHowever, the introduction of API is not enough, and the official documents are well written. I’ll take a look at a common development scenario hereReact-RouterHow to use it. Our general system will have user access restrictions, some pages may require users to have certain permissions to access. This article is to useReact-RouterTo implement a front-end authentication model.

All the code of this article has been uploaded to GitHub, you can take it down for fun: https://github.com/dennis-jiang/Front-End-Knowledges/tree/master/Examples/React/react-router-usage

Application examples

The function of this paper is a common scenario, which is to control different user roles to access different pages. There are four pages in total

  1. /index: Homepage
  2. /login: landing page
  3. /backend: background page
  4. /admin: management page

There are three other roles:

  1. User not logged in: you can only visit the home page of the website/indexAnd landing pages/login
  2. Ordinary users: you can visit the home page of the website/index, landing page/loginAnd background pages/backend
  3. administrators: you can access the administration page/adminAnd all other pages

Introducing react router

To achieve routing authentication, we have to do it step by step. First, we use react router to build a simple project with these pages. We use it directlycreate-react-appCreate a new project and then build onepagesFolder, which contains the pages we mentioned earlier:

Let’s write a simple page first. Let’s write a title first, for example:

import React from 'react';

function Admin() {
  return (
    <h1>Administrator page</h1>
  );
}

Several other pages are similar.

And then we’ll be able toApp.jsIt’s inReact-RouterDo route jump, note that we use thereact-router-dom, new versionReact-RouterThe core logic layer and the presentation layer are separated. The core logic will deal with route matching, and the presentation layer will deal with actual hops and monitoring of route changes. The reason for this is that react router not only needs to support browsers, but also needs to support react native. The monitoring and jumping of these two platforms are different, so there are several packages under react router

react-router: core logic processing, providing some common base classes

react-router-dom: the specific implementation of browser related routing monitoring and jump

react-router-native: the specific implementation of RN related routing monitoring and jump

In actual use, we generally do not need to referencereact-routerInstead, use it directlyreact-router-domThat’s fine, because it will quote itselfreact-router. Let’s introduce it into the projectreact-router-dom

import React from 'react';
import {
  BrowserRouter as Router,
  Switch,
  Route,
} from "react-router-dom";
import Home from './pages/Home';
import Login from './pages/Login';
import Backend from './pages/Backend';
import Admin from './pages/Admin';

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/login" component={Login}/>
        <Route path="/backend" component={Backend}/>
        <Route path="/admin" component={Admin}/>
        <Route path="/" component={Home}/>
      </Switch>
    </Router>
  );
}

export default App;

And then you canHomeFor pageLinkAdd the link to jump to other pages, so you can jump:

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

function Home() {
  return (
    <>
      <h1>Home page</h1>
      <ul>
        <li>< link to = / login > < link > login</li>
        <li>< link to = / backend > < link > background</li>
        <li>< link to = / Admin > administrator < / link ></li>
      </ul>
    </>
  );
}

export default Home;

Up to now, our application runs like this:

Module division

Although our jump is realized, everyone can access any page. Our previous requirement is to restrict the access to the page according to the login role. Before writing the code, let’s think about how to do this. Of course, the most intuitive and simplest way is to detect the current user’s role on each page, and report an error or jump back to the home page if it doesn’t match. We only have a few pages now, which seems to be OK. But if our application becomes bigger and more pages are added, it will be very repetitive for each page to be detected once, so we should think about this problem from a different perspective.

If you look at it carefully, there are actually three roles, corresponding to three different permissions. These three permissions also have hierarchical relationship. High level permissions include low-level permissions, so our page can be divided into three types according to these permissions:

  1. Public page: all people can access it, even without login, including the homepage and landing page of the website
  2. Normal page: the page that ordinary login users can access
  3. Administrator page: a page that only administrators can access

In order to manage these three kinds of pages, we can extract them into three files and put them in a separate folderroutesInside, three files are namedpublicRoutes.jsprivateRoutes.jsadminRoutes.js

For each routing file, we can organize such routes into arrays, and thenexportGo out and call outside, for examplepublicRoutes.js

import Login from '../pages';
import Home from '../pages/Home';

const publicRoutes = [
  {
    path: '/login',
    component: Login,
    exact: true,
  },
  {
    path: '/',
    component: Home,
    exact: true,
  },
];

export default publicRoutes;

Then the place we use outside is directly changed to:

import publicRoutes from './routes/publicRoutes';

function App() {
  return (
    <Router>
      <Switch>
        {publicRoutes.map(
          ({path, component, ...routes}) => 
            <Route key={path} path={path} component={component} {...routes}/>
        )}
        <Route path="/backend" component={Backend}/>
        <Route path="/admin" component={Admin}/>
      </Switch>
    </Router>
  );
}

This is our wayApp.jsThere won’t be a long list of routes in it. Instead, you just need to loop through an array. But we can’t directly render the pages that need to log in to access and the administrator pagesRouteComponent, we’d better encapsulate an advanced component and put the authentication work into this component, so that our ordinary pages don’t need to care about how to authenticate when they are implemented.

Encapsulating advanced components

The idea of encapsulating this authentication component is also very simple. We willpublicRoutesIt’s just a loop renderingRouteComponent, our authentication component only needs to add a logic on this basis: rendering the realRouteComponent before checking whether the current user has the corresponding permissions, if so, directly renderRouteComponent, if not, return to a page, can be a login page or background home page, specific according to their own project needs. So our routing profileprivateRoutes.jsadminRoutes.jsThe routing inside will be better than that insidepublicRoutes.jsThere are two more parameters of the

// privateRoutes.js
import Backend from '../pages/Backend';

const privateRoutes = [
  {
    path: '/backend',
    component: Backend,
    exact: true,
    Role: 'user', // the role permissions required for the current route
    Backurl: '/ Login' // route that does not satisfy permission jump
  },
];

export default privateRoutes;

adminRoutes.jsIt’s similar

// adminRoutes.js
import Admin from '../pages/Admin';

const adminRoutes = [
  {
    path: '/admin',
    component: Admin,
    exact: true,
    Role: 'admin' // the required permission is admin
    Backurl: '/ backend' // if the permission is not satisfied, jump back to the background page
  },
];

export default adminRoutes;

Then we can write our advanced component, which we callAuthRouteNow, notice that the backend API will return the current user’s role when the user logs in. A user may have multiple roles, such as the role of an ordinary user['user'], the role of the administrator is['user', 'admin']The specific permission verification logic depends on the design of your own project permissions. Here is just an example:

// AuthRoute.js
import React from 'react';
import { Route, Redirect } from 'react-router-dom';

function AuthRoute(props) {
  const {
    user: {
      role: userRole
    },
    role: routeRole,
    backUrl,
    ...otherProps
  } = props;

  //If the user has permission, the corresponding route is rendered
  if (userRole && userRole.indexOf(routeRole) > -1) {
    return <Route {...otherProps} />
  } else {
    //If you don't have permission, return the configured default route
    return <Redirect to={backUrl} />
  }
}

export default AuthRoute;

And then use ourAuthRouteRendering ofadminRoutesandprivateRoutes:

//... omit other code

{privateRoutes.map(
  (route) => <AuthRoute key={route.path} {...route}/>
)}
{adminRoutes.map(
  (route) => <AuthRoute key={route.path} {...route}/>
)}

Login setting permissions

In ourAuthRouteIt’s used in ituser: { role }This variable, but we haven’t set it yet. In real projects, when logging in, the back-end API will return the role of the current user, and then the front-end will save the permission information in some state management tools, such asRedux. We are here directlyLoginTwo buttons are written on the page to simulate this permission. The user’s configuration is based on the root component’sstateTo manage,LoginThe two buttons on the page change the correspondingstate

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

function Login(props) {
  const {loginAsUser, loginAsAdmin, history} = props;

  const userLoginHandler = () => {
    Loginasuser(); // call the parent method to set the user permissions
    history.replace ('/ backend'); // after login, jump to the background page
  }

  const adminLoginHandler = () => {
    Loginasadmin(); // call the parent method to set the administrator permissions
    history.replace ('/ admin'); // after login, jump to the administrator page
  }

  return (
    <>
      <h1>Landing page</h1>
      < button onclick = {userloginhandler} > ordinary user login < / button >
      <br/><br/>
      < button onclick = {adminloginhandler} > administrator login < / button >
      <br/><br/>
      < link to% / "> back to home < / link >
    </>
  );
}

export default Login;

Here we have completed the simple route authentication. The specific running effects are as follows:

All the code of this article has been uploaded to GitHub, you can take it down for fun: https://github.com/dennis-jiang/Front-End-Knowledges/tree/master/Examples/React/react-router-usage

summary

  1. React-RouterCan be used to manage the front-end routing jump, yesReactIt’s a very important library in ecology.
  2. React-RouterIn order to support both browser andReact-NativeHe split it into three bagsreact-routerCore package,react-router-domBrowser package,react-router-nativesupportReact-Native. There is no need to introducereact-router, just introduce the required platform package.
  3. For routes that need different permissions, we can take them out and divide them into different classes. If there are not many routes, we can export multiple arrays in one file.
  4. For the route that needs authentication, we can use an advanced component to encapsulate the logic of permission verification in it. Other pages only need to be configured, and we don’t care about authentication at all.

The content of this article is relatively simple, as a familiar referenceReact-RouterThe usage of is not bad, but we can not only use it, but also know its principle. Let’s take a look at the next articleReact-RouterThe source code contains what mystery, you can point a concern not lost, ha ha~

reference material

Official document: https://reactrouter.com/web/guides/quick-start

GitHub source code address: https://github.com/ReactTraining/react-router/tree/master/packages

At the end of the article, thank you for spending your precious time reading this article. If this article gives you a little help or inspiration, please don’t be stingy with your praise and GitHub stars. Your support is the driving force of the author’s continuous creation.

Author’s blog GitHub project address: https://github.com/dennis-jiang/Front-End-Knowledges

Recommended Today

How to Build a Cybersecurity Career

Original text:How to Build a Cybersecurity Career How to build the cause of network security Normative guidelines for building a successful career in the field of information security fromDaniel miesslerstayinformation safetyCreated / updated: December 17, 2019 I’ve been doing itinformation safety(now many people call it network security) it’s been about 20 years, and I’ve spent […]