reactjs - 登录时的每次页面刷新都会让我回到仪表板(使用受保护路由的持久登录)
问题描述
我已经实现了一个简单protected route
的 from Login
& other protected components
。
- 我
universal-cookie
用来持久化用户数据/令牌 - 在受保护的路由组件上,我确保始终检查用户是否存在或cookie 是否存在,因此用户是 LOGIN。否则,没有。这是用
Context API
受保护的路线Login.js
- 这个受保护的路由是为了确保用户 cookie 存在或用户身份验证,那么用户应该是
redirect
(Dashboard.js
登录用户的主页) ProtectedRouteLogin.js
:-
import React, { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
import { useAuth } from '../../../contexts/Auth/AuthState'
import { isAuthenticated, setLoading } from '../../../contexts/Auth/AuthAction'
const ProtectedRoute\Login = ({ component: Component, ...rest }) => {
const [authState, authDispatch] = useAuth()
const { authenticated, loading } = authState
// check if user is authenticated
useEffect(() => {
(async() => {
await isAuthenticated(authDispatch)
setLoading(authDispatch, false)
})();
}, [])
return (
<Route
{...rest} render={
props => {
if(loading) return <div className="lds-hourglass"></div>
if(!authenticated) return <Component {...props} />
else return <Redirect exact to={{
// here I redirect logged-in user to dashboard
pathname: "/dashboard",
state: { from: props.location }
}} />
}
}
/>
)
}
export default ProtectedRouteLogin
受保护的路由Dashboard.js
或其他受保护的组件
- 这与以前的目的相同,检查用户是否经过身份验证。如果是,则渲染受保护
component
的. 否则,redirect
要Login
分页 ProtectedRouteOthers.js
:-
import React, { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
import { useAuth } from '../../../contexts/Auth/AuthState'
import { isAuthenticated, setLoading } from '../../../contexts/Auth/AuthAction'
const ProtectedRouteOthers = ({ component: Component, ...rest }) => {
const [authState, authDispatch] = useAuth()
const { authenticated, loading } = authState
// check if user is authenticated
useEffect(() => {
(async() => {
await isAuthenticated(authDispatch)
setLoading(authDispatch, false)
})();
}, [])
return (
<Route
{...rest} render={
props => {
if(loading) return <div className="lds-hourglass"></div>
if(authenticated) return <Component {...props} />
else return <Redirect to={
{
// here redirect NOT logged-in user back to login page
pathname: "/login",
state: { from: props.location }
}
} />
}
}
/>
)
}
export default ProtectedRouteOthers
面临的问题
由于检查(用户身份验证)是在受保护的路由层或在任何受保护的路由之前完成的,所以每当我刷新页面(登录时)时都会遇到问题。它一直让我回到页面。
component
rendering
Dashboard.js
我想,这与我
authenticated
state
的加入有关Context API
。每次,我点击refreshed,在检查用户 cookie 是否存在之后,将在我更改/更新它之前先进入。(这是在上面两个受保护的路由中调用的函数中完成的)false
default
authenticated
state
false
default
state
isAunthenticated
Context API
isAuthenticated
功能(检查用户是否有cookie)
export const isAuthenticated = async(dispatch) => {
setLoading(dispatch, true)
// get user cookie
let userExist = getCookie('user')
/** Cookie Checking Style */
if(userExist) {
dispatch({
type: 'SET_ISAUTHENTICATED',
payload: true
})
} else {
dispatch({
type: 'SET_ISAUTHENTICATED',
payload: false
})
}
}
那么如何更改我的代码,以便每次刷新受保护的页面时(登录时)。我会留在刷新的页面上,而不是回到Dashboard
页面上吗?
解决方案
幸运的是,我找到了解决方案。但我不知道这是否是一个可接受的解决方案。至少这种逻辑对于克服我的问题是有意义的。
我决定在渲染页面和其他受保护的页面之前添加一个逻辑(在&中添加了逻辑)Login.js
components
Protected Route components
ProtectedRouteLogin.js
ProtectedRouteOthers
添加的逻辑ProtectedRouteLogin.js
- 在渲染到
Dashboard.js
页面之前,如果用户已通过身份验证,我会先检查是否已props.location.pathname
保存。如果存在/存在,那么就说。否则,只是页面cookie
render
pathname
render
Dashboard.js
ProtectedRouteLogin.js
:-
import React, { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
import { useAuth } from '../../../contexts/Auth/AuthState'
import { isAuthenticated, setLoading } from '../../../contexts/Auth/AuthAction'
import { getCookie } from '../../../services/Cookie'
const ProtectedRouteLogin = ({ component: Component, ...rest }) => {
const [authState, authDispatch] = useAuth()
const { authenticated, loading } = authState
// check if user is authenticated
useEffect(() => {
(async() => {
await isAuthenticated(authDispatch)
setLoading(authDispatch, false)
})();
}, [])
return (
<Route
{...rest} render={
props => {
if(loading) return <div className="lds-hourglass"></div>
if(!authenticated) return <Component {...props} />
else {
// get pathname save in cookie
let url = getCookie('onRefresh')
return <Redirect exact to={{
// ternary function to determine redirection
pathname: url !== '' ? url : '/pfv4-admin/dashboard',
state: { from: props.location }
}} />
}
}
}
/>
)
}
export default ProtectedRouteLogin
添加的逻辑ProtectedRouteOthers.js
- 在这里,在渲染到任何受保护
components
的之前,我将其设置为 保存即将访问的或url。所以,我可以在上面交叉检查这个url 。cookie
props.location.pathname
component
ProtectedRouteLogin.js
ProtectedRouteOthers.js
:-
import React, { useEffect } from 'react'
import { Redirect, Route } from 'react-router-dom'
import { useAuth } from '../../../contexts/Auth/AuthState'
import { isAuthenticated, setLoading } from '../../../contexts/Auth/AuthAction'
import { setCookie } from '../../../services/Cookie'
const ProtectedRouteOthers = ({ component: Component, ...rest }) => {
const [authState, authDispatch] = useAuth()
const { authenticated, loading } = authState
// check if user is authenticated
useEffect(() => {
(async() => {
await isAuthenticated(authDispatch)
setLoading(authDispatch, false)
})();
}, [])
return (
<Route
{...rest} render={
props => {
if(loading) return <div className="lds-hourglass"></div>
if(authenticated) {
// save last page seen address (url)
setCookie('onRefresh', props.location.pathname, { path: '/' })
return <Component {...props} />
}
else return <Redirect to={
{
pathname: "/pfv4-admin",
state: { from: props.location }
}
} />
}
}
/>
)
}
export default ProtectedRouteOthers
随意为这个问题添加你自己可能的解决方案。期待尝试它们。
推荐阅读
- mongodb - 显示为子文档
- node.js - Auth0 和 Dialogflow 身份验证
- angular - 如何在 ngFor 循环中获得点击的项目?
- javascript - Lodash:通过给定键连接值
- python - 在python 3中更改类变量的方法
- sql - 删除并插入
- ios - 在 viewDidLayoutSubviews() 中调用地图视图函数时,地图视图显示两次?
- selenium - 带有 chrome 浏览器的 Webdriverio 无法正确显示
- javascript - 如何检查我的浏览器是否支持媒体类型?
- python - AttributeError:模块“http.server”没有属性“ThreadingHTTPServer”