react-router v6 路由守卫/路由拦截

实现思路:封装一个高阶组件,路由鉴权高阶组件,实现未登录拦截,并跳转到登录页面,判断是否有token,如果有,就返回相对应的路由,如果没有就重定向到登录login页面
步骤:
1.在router文件中封装AuthRouter.js文件
2.在router.js中引入封装的这个高阶组件
3.登录页面实现

高阶组件的封装
router/AuthRouter.js

// 路由守卫
// 判断token是否存在(如果存在跳转主页,如果不存在跳转登录页面)

import { Navigate } from 'react-router-dom'

// 获取token方法

const getToken = () => {
    return localStorage.getItem('token')
}

// 创建一告诫组件,高阶组件就是把一个组件当作另一个组件的参数传入,然后通过判断 返回新的组件
// 下面的authRouter 就是一个高阶组件

function AuthRouter({ children }) {
    // 获取token
    const token = getToken()
    console.log(token, 'aaaa')
    // 判断token是否存在 存在直接渲染主页面
    if (token) {
        return <>{children}</>
    } else {
        return <Navigate to={'/login'}></Navigate>  //没有token跳转登录页面
    }
}
export { AuthRouter }

router/index.js

import Layout from "../pages/layout";
import Cloud from "../pages/cloud/cloud";
import State from "../pages/state/state";
import Setting from "../pages/setting/setting";
import Home from "../pages/home/home";
import Field from '../pages/cloud/field/field'
import Detail from '../pages/detail/detail'
import Cart from '../pages/cart/cart'
import Login from '../pages/login/login'
import { Navigate } from "react-router-dom";
import { AuthRouter } from "./AuthRouter";  //引入高阶组件
const routerList = [
    {
        path: '/', element: <Navigate to='/layout/home'></Navigate>
    },
    {
        path: 'layout', element: <AuthRouter><Layout></Layout></AuthRouter>, children: [
            { path: 'home', element: <Home></Home> },
            { path: 'cloud', element: <Cloud></Cloud> },
            { path: 'field', element: <Field></Field> },
            { path: 'state', element: <State></State> },
            { path: 'setting', element: <Setting></Setting> },
            { path: 'detail', element: <Detail></Detail> },
            { path: 'cart', element: <Cart></Cart> }
        ]
    },
    {
        path: 'login', element: <Login></Login>
    }
]
export default routerList

登录页面代码

import React from 'react'
import './style.css'
import axios from '../../server/request'
import { useNavigate } from 'react-router-dom'
import { Button, Checkbox, Form, Input } from 'antd';

const onFinishFailed = (errorInfo) => {
    console.log('Failed:', errorInfo);
};

export default function Login() {
    const nav = useNavigate()
    async function onFinish(values) {
        const data = await axios.post('/login', values)
        if (data.code == 200) {
            localStorage.setItem('token', JSON.stringify(data.token))
            nav('/layout/home')
        }
    };

    return (
        <div className='login'>
            <div className='box'>
                <Form
                    name="basic"
                    labelCol={{
                        span: 8,
                    }}
                    wrapperCol={{
                        span: 16,
                    }}
                    style={{
                        maxWidth: 600,
                    }}
                    initialValues={{
                        remember: true,
                    }}
                    onFinish={onFinish}
                    onFinishFailed={onFinishFailed}
                    autoComplete="off"
                >
                    <Form.Item
                        label="用户名"
                        name="username"
                        rules={[
                            {
                                pattern: /^(?:(?:\+|00)86)?1(?:(?:3[\d])|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8[\d])|(?:9[1589]))\d{8}$/,
                                required: true,
                                message: '请输入正确的手机号',
                            },
                        ]}
                    >
                        <Input />
                    </Form.Item>

                    <Form.Item
                        label="密码"
                        name="password"
                        rules={[
                            {
                                pattern: /^[a-z][0-9]{5}$/,
                                required: true,
                                message: 'Please input your password!',
                            },
                        ]}
                    >
                        <Input.Password />
                    </Form.Item>

                    <Form.Item
                        name="remember"
                        valuePropName="checked"
                        wrapperCol={{
                            offset: 8,
                            span: 16,
                        }}
                    >
                        <Checkbox>Remember me</Checkbox>
                    </Form.Item>

                    <Form.Item
                        wrapperCol={{
                            offset: 8,
                            span: 16,
                        }}
                    >
                        <Button type="primary" htmlType="submit">
                            登录
                        </Button>
                    </Form.Item>
                </Form>
            </div>
        </div>
    )
}

后端代码
下载 jsonwebtoken
引入:var jwt = require(‘jsonwebtoken’)

router.post('/login', async (req, res) => {
    let username = req.body.username
    let password = req.body.password
    console.log(username, password)
    if (!username || !password) {
        res.send({
            code: 400,
            msg: '账号和密码不能为空'
        })
    }
    let token = 'Bearer ' + jwt.sign({ username, password }, "asdf", { expiresIn: 60 * 60 * 2 })
    let user = await userModel.create({ username, password })
    if (!user) {
        return res.send({
            code: 400,
            msg: '该用户不存在'
        })
    }
    user = await userModel.findOne({ username, password })
    // console.log();
    console.log("user:0", user)
    res.send({
        code: 200,
        msg: '登录成功',
        user,
        token
    })
})
router.get('/getlist', async (req, res) => {
    let data = await shopModel.find()
    res.send({
        code: 200,
        data: data
    })
})

你可能感兴趣的:(react.js)