登录时每次刷新页面都会让我回到仪表板(使用受保护的路由持续登录)
Every page refresh while logged-in brought me back to dashboard (persistent login with protected route)
我已经从 Login
和其他 protected components
.
实现了一个简单的 protected route
- 我正在使用
universal-cookie
坚持 用户 data/token
- 在受保护的路由组件上,我确保总是检查用户是否存在或 cookie 存在 ,因此 用户是 LOGIN。否则,不。这是通过
Context API
完成的
Login.js
的受保护路线
- 这个 protected route 是为了确保 user cookie 存在 或 user authenticate , 那么用户应该是
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
或其他受保护组件的受保护路线
- 这与以前的目的相同,检查用户是否通过身份验证。如果 YES,则 render protected
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
面临的问题
因为检查(用户身份验证)在受保护的路由[=104]中完成 =] 层或 component
就在 rendering
任何 受保护的路线 之前,我遇到了一个问题,每当我 刷新 页面(登录后)。它总是让我回到 Dashboard.js
页面。
我估计,这和有关系我的authenticated
state
在Context API
是false
default
。每次,我点击 刷新,authenticated
state
将在 default
state
中排在第一个 false
直到我 change/update 它,在检查用户cookie是否存在后。 (这是在 Context API
中的 isAunthenticated
函数中完成的,该函数在上面的 Protected Routed 中被调用)
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
})
}
}
那么我如何更改我的代码,以便每次 刷新 我的 protected 页面(登录时-in).我将留在刷新的页面,而不是返回Dashboard
页面?
幸运的是我找到了解决方案。但我不知道这是否是一个可以接受的解决方案。至少这个逻辑是有意义的来解决我的问题。
我决定在呈现 Login.js
页面和其他 protected components
之前 添加逻辑 Protected Route components
(在ProtectedRouteLogin.js
& ProtectedRouteOthers
中添加的逻辑)
在ProtectedRouteLogin.js
中添加了逻辑
- 在呈现到
Dashboard.js
页面之前,如果 用户已通过身份验证 ,我会检查 props.location.pathname
已保存 在 cookie
第一个 中。如果present/exist,那么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
中添加了逻辑
- 这里,在渲染到 any protected
components
之前,我 set cookie
持有即将访问component
props.location.pathname
或url。这样,我就可以 交叉检查 这个 url 在上面 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
请随时为这个问题添加您自己的可能解决方案。期待尝试。
我已经从 Login
和其他 protected components
.
protected route
- 我正在使用
universal-cookie
坚持 用户 data/token - 在受保护的路由组件上,我确保总是检查用户是否存在或 cookie 存在 ,因此 用户是 LOGIN。否则,不。这是通过
Context API
完成的
Login.js
的受保护路线
- 这个 protected route 是为了确保 user cookie 存在 或 user authenticate , 那么用户应该是
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
或其他受保护组件的受保护路线
- 这与以前的目的相同,检查用户是否通过身份验证。如果 YES,则 render protected
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
面临的问题
因为检查(用户身份验证)在受保护的路由[=104]中完成 =] 层或
component
就在rendering
任何 受保护的路线 之前,我遇到了一个问题,每当我 刷新 页面(登录后)。它总是让我回到Dashboard.js
页面。我估计,这和有关系我的
authenticated
state
在Context API
是false
default
。每次,我点击 刷新,authenticated
state
将在default
state
中排在第一个false
直到我 change/update 它,在检查用户cookie是否存在后。 (这是在Context API
中的isAunthenticated
函数中完成的,该函数在上面的 Protected Routed 中被调用)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
})
}
}
那么我如何更改我的代码,以便每次 刷新 我的 protected 页面(登录时-in).我将留在刷新的页面,而不是返回Dashboard
页面?
幸运的是我找到了解决方案。但我不知道这是否是一个可以接受的解决方案。至少这个逻辑是有意义的来解决我的问题。
我决定在呈现 Login.js
页面和其他 protected components
之前 添加逻辑 Protected Route components
(在ProtectedRouteLogin.js
& ProtectedRouteOthers
中添加的逻辑)
在ProtectedRouteLogin.js
中添加了逻辑
- 在呈现到
Dashboard.js
页面之前,如果 用户已通过身份验证 ,我会检查props.location.pathname
已保存 在cookie
第一个 中。如果present/exist,那么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
中添加了逻辑
- 这里,在渲染到 any protected
components
之前,我 setcookie
持有即将访问component
props.location.pathname
或url。这样,我就可以 交叉检查 这个 url 在上面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
请随时为这个问题添加您自己的可能解决方案。期待尝试。