提问者:小点点

检查JWT令牌的有效性-输入前


我有一个在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("/");
  }
}

共2个答案

匿名用户

由于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调用并返回消息或重定向到登录页面。用户仍然可以浏览包含过期会话信息的页面,但将无法执行任何获取或表单操作。