React.js登录权限控制实现demo[亲测可用]

react 在项目中如果遇到有些页面是登录之后才有权限访问的情况如何处理?本文记录一下。带axios登录请求封装token跟redux封装

demo请狠狠的戳这里:http://download.lllomh.com/cliect/#/product/J702699872528330

一:目录结构

比如有四个页面组件,error  home index login  假定  home是要登录以后才能访问的话。怎么做呢?先上整体目录结构吧

二:路由router

1,在路由中 分成 map 去做,单独拆分成 路由地址:如

//routerMap.jsx


import Index from "../page/index";
import Home from "../page/home";
import ErrorPage from "../page/error";
import Login from "../page/login";
export default [
    { path: "/", name: "App", component: Index, auth: true },
    { path: "/home", name: "Home", component: Home, auth: true },
    { path: "/login", name: "Login", component: Login },
    { path: "/404", name: "404", component: ErrorPage },
];

2,把权限配置封装部分拿出来:如

//FrontendAuth.jsx
import React, { Component } from "react";
import { Route, Redirect } from "react-router-dom";
class FrontendAuth extends Component {
    // eslint-disable-next-line no-useless-constructor
    constructor(props) {
        super(props);
    }
    render() {
        const { routerConfig, location } = this.props;
        const { pathname } = location;
        const isLogin = sessionStorage.getItem("username");
        console.log(pathname, isLogin);
        console.log(location);
        // 如果该路由不用进行权限校验,登录状态下登陆页除外
        // 因为登陆后,无法跳转到登陆页
        // 这部分代码,是为了在非登陆状态下,访问不需要权限校验的路由
        const targetRouterConfig = routerConfig.find(
            (item) => item.path === pathname
        );
        console.log(targetRouterConfig);
        if (targetRouterConfig && !targetRouterConfig.auth && !isLogin) {
            const { component } = targetRouterConfig;
            return <Route exact path={pathname} component={component} />;
        }
        if (isLogin) {
            // 如果是登陆状态,想要跳转到登陆,重定向到主页
            if (pathname === "/login") {
                return <Redirect to="/" />;
            } else {
                // 如果路由合法,就跳转到相应的路由
                if (targetRouterConfig) {
                    return (
                        <Route path={pathname} component={targetRouterConfig.component} />
                    );
                } else {
                    // 如果路由不合法,重定向到 404 页面
                    return <Redirect to="/404" />;
                }
            }
        } else {
            // 非登陆状态下,当路由合法时且需要权限校验时,跳转到登陆页面,要求登陆
            if (targetRouterConfig && targetRouterConfig.auth) {
                return <Redirect to="/login" />;
            } else {
                // 非登陆状态下,路由不合法时,重定向至 404
                return <Redirect to="/404" />;
            }
        }
    }
}
export default FrontendAuth;

3,最后集合弹出:

//index/jsx

import React, { Component } from "react";
import { BrowserRouter as Router, Switch } from "react-router-dom";
import axios from '../util/axiosTool'
import * as Tool from "../util/tool"
import FrontendAuth from "./FrontendAuth";
import routerMap from "./routerMap";

React.Component.prototype.$axios = axios;
React.Component.prototype.$Tool = Tool;

class Routers extends Component {
    // eslint-disable-next-line no-useless-constructor
    constructor(props) {
        super(props);
    }
    render() {
        return (
            <Router>
                <div>
                    <Switch>
                        <FrontendAuth routerConfig={routerMap} />
                    </Switch>
                </div>
            </Router>
        );
    }
}

export default Routers;

三:页面组件

1,login 

import React, { Component } from "react";
import { Redirect } from "react-router-dom"; //重定向使用
class Login extends Component {
    constructor(props) {
        super(props);
        this.state = {
            username: "",
            password: "",
            rediectToReferrer: false, // 是否重定向之前的界面
        };
        this.handleChange = this.handleChange.bind(this);
        this.handleSumit = this.handleSumit.bind(this);
    }
    // 处理用户名、密码的变化
    handleChange(e) {
        if (e.target.name === "username") {
            this.setState({
                username: e.target.value,
            });
        } else if (e.target.name === "password") {
            this.setState({
                password: e.target.value,
            });
        }
    }
    // 提交登录表单
    async handleSumit(e) {
        e.preventDefault();
        const username = this.state.username;
        const password = this.state.password;
        if (username.length === 0 || password.length === 0) {
            alert("用户名或密码不能为空!");
            return;
        }
        // 保存信息到sessionStorage
        sessionStorage.setItem("username", username);
        // 登录成功后,设置redirectToReferrer为true;
        this.setState({
            rediectToReferrer: true,
        });
        let RedirectUrl = this.props.location.state
            ? this.props.location.state.from.pathname
            : "/";
        // 登陆成功之后的跳转
        this.props.history.push(RedirectUrl);
    }
    render() {
        return (
            <form className="login" onSubmit={this.handleSumit}>
                <div>
                    <label htmlFor="">
                        用户名:
                        <input
                            type="text"
                            name="username"
                            value={this.state.username}
                            onChange={this.handleChange}
                        />
                    </label>
                </div>
                <div>
                    <label htmlFor="">
                        密码:
                        <input
                            type="password"
                            name="password"
                            value={this.state.password}
                            onChange={this.handleChange}
                        />
                    </label>
                </div>
                <input type="submit" value="登录" />
            </form>
        );
    }
}
export default Login;

登录页面视图:

即可,在没登录的时候 是无法访问 home的  在 map里面用  auth: true 来区分,可以结合token来一起使用。

本demo已经携带了 token 加入请求header 封装。

动图权限测试:未登录不许可访问home

原文地址:https://www.cnblogs.com/lllomh/p/14991886.html