首页 > 解决方案 > VueJS / Vuex App - 验证用于身份验证的 JWT 令牌

问题描述

我有一个 VueJS 应用程序,使用 Vuex 和 Vue 路由器。我有 3 个组件(也是页面):主页、登录和一个需要进行身份验证的受保护页面。

登录页面对后端 API 进行 POST 调用,如果凭据有效,该 API 将返回一个令牌。

  methods: {
    sendCredentials: function() {
      const { email, password } = this
      this.$store.dispatch(AUTH_REQUEST, {email, password})
      .then(() => {
          this.$router.push('/')
      })
      .catch((err) => console.log(err.response));
    }
  }

以下是相关操作:

actions: {
    [AUTH_REQUEST]: ({ commit, dispatch }, user) => {
        return new Promise((resolve, reject) => {
            commit(AUTH_REQUEST);
            axios.post('http://localhost:3000/api/login', user)
                .then((resp) => {
                    const token = resp.data.token;
                    localStorage.setItem('userToken', token);
                    commit(AUTH_LOGIN, token);
                    resolve(resp);
                })
                .catch(err => {
                    commit(AUTH_ERROR, err);
                    localStorage.removeItem('userToken');
                    reject(err);
                })

        });
    }

如果用户未登录,我已使用导航防护来阻止对受保护页面的访问。

这实际上是有效的:当我进入受保护的页面时,我被要求登录。当我使用权限凭据时,我能够访问受保护的页面。

我还有一个巨大的错误:当我将任何随机字符串作为 userToken 放在 localStorage 上时,我可以访问受保护的页面......

如何预防?

初始状态定义如下:

state: {
    token: localStorage.getItem('userToken') || '',
},

当我设置 token 的初始状态时,有没有办法验证我通过 localStorage 获得的 userToken ?

标签: authenticationvue.jsjwtvuexvue-router

解决方案


不久前我一直在想同样的事情。我最终得到的是在初始加载页面时针对您的后端检查令牌。如果令牌有效,则将其提交给 Vuex,如果令牌无效,则从 localStorage 中删除所有内容。

这导致结果有人假设可以在初始加载后用他们自己的无效令牌替换令牌,但是如果客户端令牌已经过验证,那还有什么意义呢?如果您也想保护这种情况,您可以在导航防护中应用相同的逻辑。因此,不仅要检查令牌,还要在每次路由更改时针对后端验证令牌,如果无效则清除 localStorage。尽管由于额外的 API 调用,我认为这会降低性能。


推荐阅读