react登錄路由控制


登錄訪問控制

  • AuthRoute 鑒權路由組件實現思路
  • 參照官網自己封裝AuthRoute 鑒權路由組件
  • 實現修改登錄成功后的跳轉

概述

項目中的兩種類型的功能和兩種類型的頁面:

兩種功能:

  • 登錄后才能進行操作(比如:獲取個人資料)
  • 不需要登錄就可以操作(比如:獲取房屋列表)

兩種頁面:

  • 需要登錄才能訪問(比如:個人中心頁)
  • 不需要登錄即可訪問(比如:首頁)

對於需要登錄才能操作的功能使用 axios 攔截器 進行處理(比如:統一添加請求頭 authorization等)

對於需要登錄才能訪問的頁面使用 路由控制

功能處理-使用axios攔截器統一處理token

  • 在api.js 中,添加請求攔截器 (API.interceptors.request.user())
  • 獲取到當前請求的接口路徑(url)
  • 判斷接口路徑,是否是以/user 開頭,並且不是登錄或注冊接口(只給需要的接口添加請求頭)
  • 如果是,就添加請求頭Authorization
// 添加請求攔截器
API.interceptors.request.use(config => {
  const { url } = config
  // 判斷請求url路徑
  if (
    url.startsWith('/user') &&
    !url.startsWith('/user/login') &&
    !url.startsWith('/user/registered')
  ) {
    // 添加請求頭
    config.headers.Authorization = getToken()
  }
  return config
})
  • 添加響應攔截器 (API.interceptors.response.use())
  • 判斷返回值中的狀態碼
  • 如果是400,標示token超時或異常,直接移除token
// 添加響應攔截器
API.interceptors.response.use(response => {
  const { status } = response.data
  if (status === 400) {
    // 此時,說明 token 失效,直接移除 token 即可
    removeToken()
  }
  return response
})

頁面處理-AuthRoute鑒權路由組件

實現原理

  • 限制某個頁面只能在登陸的情況下訪問,但是在React路由中並沒有直接提供該組件,需要手動封裝,來實現登陸訪問控制(類似與Vue路由的導航守衛)

  • 參數 react-router-dom的鑒權文檔

  • AuthRoute 組件實際上就是對原來Route組件做了一次包裝,來實現一些額外的功能

    • 使用

  • render方法:render props模式,指定該路由要渲染的組件內容

  • Redirect組件:重定向組件,通過to屬性,指定要跳轉的路由信息

// 官網封裝的核心邏輯代碼
// ...rest  把之前的組件中傳遞的屬性原封不動傳遞過來
function PrivateRoute({ component: Component, ...rest }) {
  return (
    <Route
      {...rest}
      // render方法: render props模式,指定該路由要渲染的組件內容
      render={props =>
        // 判斷是否登陸,如果登陸,跳轉配置的component,如果沒有登陸,利用 Redirect組件來進行重定向
        fakeAuth.isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              // 把當前的頁面路徑保存起來,方便用戶登錄后能夠跳回當前頁面
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}

封裝AuthRoute鑒權路由組件

  • 在components目錄中創建AuthRoute/index.js 文件
  • 創建組件AuthRoute並導出
  • 在AuthRoute組件中返回Route組件(在Route基礎上做了一層包裝,用於實現自定義功能)
  • 給Route組件,添加render方法,指定改組件要渲染的內容(類似與component屬性)
  • 在render方法中,調用isAuth() 判斷是否登陸
  • 如果登陸了,就渲染當前組件(通過參數component獲取到要渲染的組件,需要重命名)
  • 如果沒有登陸,就重定向到登陸頁面,並且指定登陸成功后腰跳轉的頁面路徑
  • 將AuthRoute組件接收到的props原樣傳遞給Route組件(保證與Route組件使用方式相同)
  • 使用AuthRoute組件配置路由規則,驗證是否實現頁面的登陸訪問控制
const AuthRoute = ({ component: Component, ...rest }) => {
  return (
    <Route
      {...rest}
      render={props => {
        const isLogin = isAuth()

        if (isLogin) {
          // 已登錄
          // 將 props 傳遞給組件,組件中才能獲取到路由相關信息
          return <Component {...props} />
        } else {
          // 未登錄
          return (
            <Redirect
              to={{
                pathname: '/login',
                state: {
                  from: props.location
                }
              }}
            />
          )
        }
      }}
    />
  )
}
export default AuthRoute

修改登錄成功跳轉

  • 登陸成功后,判斷是否需要跳轉到用戶想要訪問的頁面(判斷props.location.state 是否有值)
  • 如果不需要,則直接調用history.go(-1) 返回上一頁
  • 如果需要,就跳轉到from.pathname 指定的頁面(推薦使用replace方法模式,不是push)
 // 表單的提交事件
  handleSubmit: async (values, { props }) => {
    ...
    if (status === 200) {
      // 登錄成功
      localStorage.setItem('hkzf_token', body.token)

      /* 
        1 登錄成功后,判斷是否需要跳轉到用戶想要訪問的頁面(判斷 props.location.state 是否有值)。
        2 如果不需要(沒有值),則直接調用 history.go(-1) 返回上一頁。
        3 如果需要,就跳轉到 from.pathname 指定的頁面(推薦使用 replace 方法模式,而不是 push)。
      */
      if (!props.location.state) {
        // 此時,表示是直接進入到了該頁面,直接調用 go(-1) 即可
        props.history.go(-1)
      } else {
        // replace: [home, map]
        props.history.replace(props.location.state.from.pathname)
      }
    } else {
      // 登錄失敗
      Toast.info(description, 2, null, false)
    }
  }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM