React项目 鉴权功能

1,875 阅读2分钟

React项目 鉴权功能

场景:

  • 有的页面需要用户先登录才可以访问
  • 有的功能需要用户先登录才可以使用
  • 有的功能需要确认用户是否拥有权限

如果有redux,其实把鉴权信息放在redux就可以,如果项目没有使用redux,那么就可以通过以下方式实现

实现原理:

  • 创建一个 contextcontext.Provider向下注入的值是一个包含 响应性的state+修改state的方法 的对象,并在根组件向下注入,这样,下面的组件随时可以调用 useContext 获取上述对象,进而实现全局同步鉴权信息

实现步骤

  • 创建 auth context

    src/contexts/authContext.js 文件中

    // 鉴权context
    import { createContext } from "react";
    ​
    const auth = createContext();
    ​
    export default auth;
    
  • 书写鉴权功能

    src/utils/useProvideAuth.js 文件中

    import { useState } from "react"// 提供鉴权功能
    const useProvideAuth = () => {
      // auth为true,代表已登录、已鉴权。默认为未鉴权
      const [auth, setAuth] = useState(false);
      // 更新鉴权
      const updateAuth = (newState, cb) => {
        setAuth(newState);
        cb && cb();
      }
    ​
      return {
        auth,
        updateAuth
      }
    }
    ​
    export default useProvideAuth;
    
  • 创建提供鉴权的组件

    其实如果 根组件App是用 function Component函数式组件 创建的话,可以不需要这步,直接在 根组件 中Provider,因为我们当前项目是 class Component类组件,不可以使用 useState Hooks,所以我们要再创建一个 函数式组件进行注入。

    src/utils/AuthProvider.jsx

    // 提供鉴权的组件import React from "react";
    // 导入 鉴权功能
    import useProvideAuth from "./useProvideAuth";
    // 导入 鉴权Context
    import auth from "../contexts/authContext"function AuthProvider({ children }) {
      return (
        <auth.Provider value={useProvideAuth()}>
          {children}
        </auth.Provider>
      )
    }
    ​
    export default AuthProvider;
    
  • main.jsx中,给根组件包裹 AuthProvider

    import React from 'react'
    import ReactDOM from 'react-dom'
    ....
    // 引入根组件
    import App from './App';
    ​
    // 导入路由
    import { HashRouter } from "react-router-dom";
    ​
    // 导入鉴权组件
    import AuthProvider from "./utils/AuthProvider.jsx"ReactDOM.render(
      <AuthProvider>
        <HashRouter>
          <App></App>
        </HashRouter>
      </AuthProvider>
      ,
      document.getElementById('root')
    )
    
  • 在遇到需要鉴权功能时:

    使用 useContext 获取鉴权功能,进行使用

    /**
     * 找房页面
     * 
     * FindHouse
     */import React, { useContext } from "react";
    import { Button, Toast } from "antd-mobile";
    ​
    // 导入鉴权Context
    import authContext from "@/contexts/authContext"function FindHouse() {
      // 获取 鉴权功能
      const auth = useContext(authContext);
        
      //  需要登录的操作
      const operationNeedLogin = () => {
        // 判断是否鉴权
        if (!auth.auth) {
          return Toast.show("需要登录才可以");
        }
        Toast.show("可以操作")
      }
    ​
      return (
        <div>
          <h3>找房页面</h3>
          {/* 需要登录的操作 */}
          <Button type="ghost" onClick={operationNeedLogin}>需要登录的操作</Button>
        </div>
      )
    }
    ​
    export default FindHouse;
    
  • 再遇到需要鉴权才能访问的页面时

    import React, { useContext } from "react"
    import authProvider from "@/contexts/authContext";
    import { Redirect } from "react-router";
    // 一个需要登录才能访问的页面
    function News(props) {
      const auth = useContext(authProvider);
    ​
    ​
      return (
        // 是否鉴权,未登录跳转到登录页
        auth.auth ?
          <div>
            <h2>News</h2>
            <p>假设这是一个需要登录才可以访问的页面</p>
          </div>
          :
          <Redirect to="/login"></Redirect>
      )
    }
    ​
    export default News;
    

总结

  • 其实完成这个功能的思想,不只可以用于 全局鉴权,这个思想 本质上就是全局通信的一种实现。

学习来源:reactrouter.com/web/example…