我有一个在Vue路由器中运行“beforeEnter”的函数,用于验证用户是否已通过身份验证,否则会触发消息。
它检查(jwt)令牌是否保存在
localStorage
中-如果用户手动注销,这会起作用,因为它会从localStorage
中删除令牌。但是,当令牌过期时,它仍然保留在localStorage
中,因此函数认为((localStorage.token)
)用户已登录。
由于令牌无效,服务器仍然阻止任何请求,因此是安全的。
在页面加载之前,如何在服务器端的“beforeEnter”中间件中检查令牌的有效性?
我是否需要创建一个endpoint来检查令牌的有效性并返回结果?(我正在使用fetch(),但我见过有人使用axios拦截器…)
没有任何价值,我没有使用VUEX,似乎有更多的细节?
function protectedPage(to, from, next) {
if (localStorage.token) {
next();
} else {
Vue.toasted.show("The session has ended. Please login.", {
theme: "toasted-primary",
position: "top-center",
duration: null,
action: {
text: "Login",
onClick: (e, toastObject) => {
next("/");
toastObject.goAway(0);
}
}
});
next("/");
}
}
由于exp
是有效负载的一部分,而JWT只是一个base64字符串,因此您可以对其进行解码并在Vue应用程序上检查exp
时间。
这是一个解码JWT令牌并获取有效载荷的函数(取自此处)
function parseJwt (token) {
var base64Url = token.split('.')[1];
var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
var jsonPayload = decodeURIComponent(Buffer.from(base64, "base64").toString("ascii").split("").map(function(c) {
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join(''));
return JSON.parse(jsonPayload);
};
并在您的beforeRouteEnter
功能中进行检查:
beforeRouteEnter (to, from, next) {
if (localStorage.token) {
const jwtPayload = parseJwt(localStorage.token);
if (jwtPayload.exp < Date.now()/1000) {
// token expired
deleteTokenFromLocalStorage();
next("/");
}
next();
} else {
next("/");
}
},
您真的不需要在后端服务器上检查它,因为解码JWT令牌负载并在客户端签入它不会带来安全问题。此外,每次用户访问路由时,它都会为您节省一个HTTP请求。
您需要一个后端中间件,它绑定到每个API调用,并验证用户会话是否仍然存在并具有相同的令牌。
如果会话已过期或令牌已更改且与当前用户会话不匹配,则可以从后端将用户重定向到登录页面,并强制他创建新会话。
我认为您不需要获取每个路由入口的身份验证,只需阻止后端api调用并返回消息或重定向到登录页面。用户仍然可以浏览包含过期会话信息的页面,但将无法执行任何获取或表单操作。