我发现很难理解当令牌过期并执行注销操作时,最后一个操作仅在页面刷新时执行。虽然当令牌过期时抛出401代码,但它仍然使受保护的路由可见,并且只有在刷新时才会退出并进入login..它应该是这样的还是不应该发生,我错过了什么?
前面的代码是
import React, { useEffect } from 'react';
import { Route, Redirect } from 'react-router-dom';
import {useDispatch} from 'react-redux'
import { logoutUser } from '../redux/ActionCreators';
import { baseUrl } from '../shared/baseUrl'
export const PrivateRoute = ({ component: Component, ...rest }) => {
const dispatch = useDispatch()
useEffect(() => {
// send jwt to API to see if it's valid
let token = localStorage.getItem("token");
if (token) {
fetch(baseUrl + "protected", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ token })
})
.then((res) => {
return res.json()
})
.then((json) => {
if (json.success) {
}
})
.catch((err) => {
dispatch(logoutUser())
})
} else {
dispatch(logoutUser())
}
}, [])
return (<Route {...rest} render={props => (
localStorage.getItem('token')
? <Component {...props} />
: <Redirect to={{ pathname: '/users/login', state: { from: props.location } }} />
)} />)
}
和API
protectedRouter.route('/')
.options(cors.corsWithOptions, (req, res) => { res.sendStatus(200) })
.get(cors.cors, authenticate.verifyUser, authenticate.verifyAdmin, async (req, res, next) => {
res.statusCode = 403
res.end('Operation not supported')
})
.post(cors.corsWithOptions, async (req, res, next) => {
const token = req.body.token
if (token) {
try {
return jwt.verify(token, process.env.secretKey);
} catch (err) {
return null;
}
}
return null;
})
可以有多种解决方法,最简单的方法就是重新呈现组件。举个例子。可能不是最干净的,但它会给你一个想法
const dispatch = useDispatch();
const { token, setToken } = useDispatch();
useEffect(() => {
// send jwt to API to see if it's valid
const token_from_storage = localStorage.getItem("token");
setToken(token_from_storage);
if (token_from_storage) {
fetch(baseUrl + "protected", {
method: "POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({ token })
})
.then((res) => {
return res.json()
})
.then((json) => {
if (json.success) {
}
})
.catch((err) => {
setToken(undefined);
dispatch(logoutUser())
})
} else {
setToken(undefined);
dispatch(logoutUser())
}
}, [])
return (<Route {...rest} render={props => (
token
? <Component {...props} />
: <Redirect to={{ pathname: '/users/login', state: { from:
props.location } }} />
)} />)
当令牌无效或从存储中找不到令牌时,它将重新呈现组件。HTH .