【React】路由鉴权

需求

  1. 未登录状态下,某些页面不可访问,白名单中的页面可以。
  2. 未登录状态下,拦截通过修改url直接访问页面。
  3. 判断是否有权访问某些页面。
  4. 路由规则中每个页面都需要调用某个接口。

前提

使用的react-router-dom6 ,这里只是举例,具体细节根据项目调整。

路由表生成路由规则

import { Navigate, Outlet, RouteObject, useRoutes } from "react-router-dom"

import MyLayout from "@/layout/index"
// 无需Layout的组件
import Login from "@/views/Login/Login"
import NotFound from "@/views/NotFound/NotFound"
// 组件
import Dashboard from "@/views/Dashborad/Dashboard"
import Project from "@/views/Project/Project"
import Test1 from "@/views/Setting/Test1"
import Test2 from "@/views/Setting/Test2"
import Test3 from "@/views/Test/Test3"
import Test4 from "@/views/Test/Test4"

const router_items: RouteObject[] = [
  {
    path: "/",
    element: <MyLayout />,
    children: [
      {
        path: "",
        element: <Navigate to="/dashboard" />, // 重定向
      },
      {
        path: "dashboard",
        element: <Dashboard />,
      },
      {
        path: "project",
        element: <Project />,
      },
      {
        path: "setting",
        element: <Outlet />, // 占位符
        children: [
          { path: "test1", element: <Test1 /> },
          { path: "test2", element: <Test2 /> },
        ],
      },
      {
        path: "test",
        element: <Outlet />, // 占位符
        children: [
          { path: "test3", element: <Test3 /> },
          { path: "test4", element: <Test4 /> },
        ],
      },
    ],
  },
  // 不需要layout的页面写到外面
  {
    path: "login",
    element: <Login />,
  },
  { path: "*", element: <NotFound /> },
]

export default () => {
  // 根据路由表生成对应的路由规则
  const ElementRouter = useRoutes(router_items)
  return ElementRouter
}

上述路由规则会在<MyLayout />中声明的位置处展示

在这里插入图片描述
APP中注册路由

// 路由
import GetRouter from "./router"

function App() {
  const RouterElement = GetRouter()
  return <>{RouterElement}</>
}

export default App

实现步骤

先创建高阶组件名为AuthRouter,并在main.tsx中引入并包裹APP。
高阶组件指接收一个组件并返回增强后的该组件。

AuthRouter

const AuthRouter = (props: { children: JSX.Element }) => {
  return props.children
}

export default AuthRouter
import ReactDOM from "react-dom/client"
import App from "./App.tsx"
import "./index.scss"
// router
import { BrowserRouter as Router } from "react-router-dom"
import AuthRouter from "@/HOC/AuthRouter.tsx" // 高阶组件


ReactDOM.createRoot(document.getElementById("root")!).render(
  <Router>
        <AuthRouter>
          <App />
        </AuthRouter>
  </Router>
)

token相关

一、token失效重定向到login

AuthRouter

import { Navigate, useLocation } from "react-router-dom"

const AuthRouter = (props: { children: JSX.Element }) => {
  const { pathname } = useLocation()

  let token = "sdnfowe623ognis"
  if (pathname === "/login") {
    return props.children
  }
  if (!token) {
    return <Navigate to="/login" replace />
  } else {
    return props.children
  }
}

export default AuthRouter

二、白名单无需判断token

AuthRouter

import { Navigate, useLocation } from "react-router-dom"

const AuthRouter = (props: { children: JSX.Element }) => {
  const { pathname } = useLocation()
  
  const whiteList = ["/login", "/test/test4"] // 声明白名单
  
  let token = "sdnfowe623ognis"
  // 白名单直接放行
  if (whiteList.includes(pathname)) {  
    return props.children
  }
  if (!token) {
    return <Navigate to="/login" replace />
  } else {
    return props.children
  }
}

export default AuthRouter

权限相关

基本同白名单逻辑

AuthRouter

import { useLocation } from "react-router-dom"

const AuthRouter = (props: { children: JSX.Element }) => {
  const { pathname } = useLocation()

  let auth_list = ["/login", "/dashboard"] // 权限只能访问这些路由
  if (!auth_list.includes(pathname)) {
    return (
      <div>
        <h2>暂无权限</h2>
      </div>
    )
  }
  return props.children
}

export default AuthRouter

当访问无权路由时,展示如下:

在这里插入图片描述

每个页面都需要调用的函数

假如某些接口数据作用于全局且总会改变,如用户信息等,也可以写到AuthRouter中。
注意:只有处于登录态需要调用该函数的路由,才能调用。

AuthRouter

import { Navigate, useLocation } from "react-router-dom"
import API from "@/api"

const AuthRouter = (props: { children: JSX.Element }) => {
  const { pathname } = useLocation()

  // 不需要获取用户信息的路由
  const notGetUserInfoRouteList: string[] = [
    "/login",
    "/register",
    "/test/test4",
  ]

  let token = "dsnfoiwne23"
  if (!token) {
    return <Navigate to="/login" replace />
  } else {
    // 有token 且 需要调用
    if (!notGetUserInfoRouteList.includes(pathname)) {
      API.getUserInfo().then(({ code, data }) => {
        ...
      })
    }
    return props.children
  }
}

export default AuthRouter

上面的API是封装好的请求,具体可看另一篇文章:TS封装axios并约束请求参数以及响应的类型

整体代码

import { Navigate, useLocation } from "react-router-dom"
import cookie from "react-cookies"
import API from "@/api"

const AuthRouter = (props: { children: JSX.Element }) => {
  const { pathname } = useLocation()

  const whiteList: string[] = ["/login", "/test/test4"] // 白名单(无需登录)
  const noUserInfoList: string[] = [...whiteList, "/register"] // 不需要调用 getuserinfo 的路由
  const authList: string[] = ["/login", "/dashboard"] // 权限只能访问这些路由

  if (!authList.includes(pathname)) {
    return (
      <div>
        <h2>无权访问该页面</h2>
      </div>
    )
  }
  // 如果当前路由不在白名单中,且没有 token,则重定向到登录页
  if (!whiteList.includes(pathname) && !cookie.load("token")) {
    return <Navigate to="/login" replace />
  }

  // 如果当前路由需要调用 getuserinfo 接口,就调用它
  if (!noUserInfoList.includes(pathname)) {
    API.getUserInfo().then(({ code, data }) => {
      ...
    })
  }

  // 返回子组件
  return props.children
}

export default AuthRouter

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/535344.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HarmonyOS开发实例:【数字管家app】

一&#xff0e;概述 本应用是基于RK3399开发板&#xff0c;使用OpenHarmony3.1-Release开发的应用。通过OpenHarmony的分布式技术&#xff0c;使多人能够一起画画。 1.应用运行效果图&#xff1a; 2.分布式画板使用示意图 如上图所示&#xff0c;用户1、用户2在各自本地端进行…

AcWing 1111. 字母 解题思路及代码

先贴个题目&#xff1a; 简单的dfs&#xff0c;没啥难点&#xff0c;直接上代码。 #include<iostream> #include<cmath> using namespace std;const int N 30;int r, s; int ans 0; char map[N][N]; bool st[26]; int dx[4] {0, 0, -1, 1}, dy[4] {1, -1, 0, …

stack的简单实现

stack的简单实现 适配器模式stack的实现代码实现 为什么没有迭代器的实现&#xff1f;实际默认容器是deque&#xff08;了解即可&#xff09;dequedeque的优缺点 谢谢观看 适配器模式 stack和我们之前学的list 和 vector 不一样采用的适配器模式 什么叫适配器呢&#xff1f;我…

【前端Vue】Vue3+Pinia小兔鲜电商项目第5篇:整体认识和路由配置,本资源由 收集整理【附代码文档】

Vue3ElementPlusPinia开发小兔鲜电商项目完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;认识Vue3&#xff0c;使用create-vue搭建Vue3项目1. Vue3组合式API体验,2. Vue3更多的优势,1. 认识create-vue,2. 使用create-vue创建项目,1. setup选项的写法和执行…

LinkedHashMap 是如何保证返回的顺序性的?

LinkedHashMap 源码阅读 public class LinkedHashMap<K,V>extends HashMap<K,V>implements Map<K,V>先来看一下 LinkedHashMap 的继承关系&#xff0c;它继承了 HashMap&#xff0c;并且实现了 Map 接口。 LinkedHashMap 底层是 数组 链表 的形式&#xf…

Eland上传bge-base-zh-v1.5向量化模型到ElasticSearch中

最近需要做一些向量检索&#xff0c;试试ES 一、准备 系统&#xff1a;MacOS 14.3.1 ElasticSearch&#xff1a;8.13.2 Kibana&#xff1a;8.13.2 本地单机环境&#xff0c;无集群&#xff0c;也不基于Docker BGE是一个常见的文本转向量的模型&#xff0c;在很多大模型RAG应…

RK3588平台开发系列讲解(GMAC delay开发篇)

目录 RGMII Delayline 获取步骤 代码确认 节点确认 扫描 delayline 窗口 测试扫描出来的中间值 自动扫描 硬件 RGMII Delayline 获取步骤 如果你的项目具有千兆以太网功能&#xff0c;使用的是 RGMII 接口&#xff0c;只要有硬件差别&#xff0c;都需要重新做一次 delay…

今天讲讲MYSQL数据库事务怎么实现的!

目录 什么是数据库事务 Mysql如何保证原子性 Mysql如何保证持久性 MySQL怎么保证隔离性 事务隔离级别 脏读的解决 不可重复读的解决 幻读的解决 MVCC实现 Read View 那么RC、RR级别下的InnoDB快照读有什么不同&#xff1f; 什么是数据库事务 数据库事务是指一组数据…

鸿蒙让我赚到了第一笔桶金!年薪33.6W!

抢人&#xff01;抢人&#xff01;抢人&#xff01; 所谓抢滩鸿蒙&#xff0c;人才先行。鸿蒙系统火力全开后&#xff0c;抢人已成鸿蒙市场的主题词&#xff01; 智联招聘数据显示&#xff0c;春节后首周&#xff0c;鸿蒙相关职位数同比增长163%&#xff0c;是去年同期的2.6倍…

【包编译】库文件安装错位置怎么办

背景&#xff1a; 在建图的工作空间mapping中&#xff0c;编译好了GeographphicLib-2.3之后&#xff0c;对工作空间mapping进行编译&#xff0c;报错&#xff0c;找不到下面这俩。 总结&#xff1a; 原因&#xff1a;因为GeographphicLib的库文件在编译的时候没有放到默认系统…

“人工智能+数字人”,让数字技术赋能多领域智能化管理、数字化服务

AI数字人结合了语音合成、语音识别、语义理解、图像处理、虚拟形象驱动等多项AI核心技术&#xff0c;可以实现导览服务、信息播报、互动交流、业务咨询等智能化功能。 如今&#xff0c;AI数字人逐渐被政务、文旅、展馆展厅、博物馆、数字会议、金融、校园等等领域多元化应用&am…

springboot如何切换内置web服务器?

切换内置web服务器 这是没有引入web依赖的服务 这是引入web依赖的服务 由此可知默认是tomcat服务器 那么如何切换内置服务器 只要有对应服务器的坐标即可自动切换&#xff0c;先排除tomcat再引入依赖&#xff0c;比如切换成jetty服务器 <dependency><groupId>org…

SQL Serve---查询

概要 1、order by子句 —默认asc&#xff08;升序&#xff09;、desc&#xff08;降序&#xff09; 2、distinct关键字 3、group by子句 4、聚合函数 —max()、min()、sum()、avg()、count() 5、having子句 6、compute子句 英文关键字 order by 排序 asc…

【SpringBoot整合系列】SpringBoot整合FastDFS(二)

目录 SpringBoot整合FastDFSJava客户端/依赖常用api接口解释1.uploadFile参数返回值 2.uploadSlaveFile参数返回值 3.getMetadata参数返回值 4.overwriteMetadata参数&#xff1a;返回值&#xff1a;无 5.mergeMetadata参数&#xff1a;返回值&#xff1a;无 6.queryFileInfo参…

linux重定向符号

将ls命令执行结果重定向到a文件中 将错误ls命令执行结果重定向到a文件中&#xff08;这里用到前面的标准错误输出重定向&#xff09;

python linux服务器ssh简单爆破(测试用户名密码)(连接ssh服务器)(测试登录ssh服务器)

文章目录 背景示例代码代码解释导入模块SSH服务器的地址和端口用户名和密码列表生成所有可能的用户名和密码组合尝试连接到SSH服务器并验证用户名和密码遍历并测试每一对凭证 背景 我们华为摄像头linux终端的密码忘了&#xff0c;还不太好初始化&#xff0c;手动一个个测试太麻…

宏观认知第一篇--AI 是否就是第四次工业革命?

今年春节期间李一舟老师突然爆火&#xff0c;成功晋升为能与 ChatGPT 公司 CEO 齐名的中国 AI 大佬&#xff0c;赚到几个小目标后又火速被封&#xff0c;于是想着有空写篇小文章讲一讲跟普通人切身相关的话题-- AI 是否就是第四次工业革命&#xff1f; “AI 是否就是第四次工业…

数学杂谈之三:数学思想方法

数学杂谈之三&#xff1a;数学思想方法 数学杂谈之一&#xff1a;数学的形态 https://blog.csdn.net/cnds123/article/details/137437208 数学杂谈之二&#xff1a;数学中的概念和理解 https://blog.csdn.net/cnds123/article/details/137500537 数学思维、数学思想和数学方法…

SpringBoot学习(一)引入、分析、核心

文章目录 SpringBoot特性示例总结简化整合简化开发简化配置简化部署简化运维 Spring Initializer创建向导 应用分析依赖管理机制自动配置机制初步理解完整流程 SpringBoot学习点 核心技能常用注解YAML配置文件基本语法示例辅助工具lombok 日志配置简介格式组成记录日志日志级别…

看AI赋能数智化 | Gooxi AI服务器闪耀CITE 2024

4月9日“中国电子信息博览会暨2024 AI算力产业大会”在深圳如期开展&#xff0c;Gooxi携最新产品、行业应用全栈解决方案出席盛会&#xff0c;全面展示Gooxi回应数智新时代下机遇与挑战的丰富AI创新实践成果。 All in AI&#xff0c;奔赴新质生产力 作为中国领先的服务器解决…