首页 > 解决方案 > 如何使用 Nuxt Auth 模块在 Vuex 中保存 JWT 令牌?

问题描述

我目前正在尝试使用 VueJS 将 VueJS 页面转换为 NuxtJS。不幸的是,我在验证用户时遇到了一些问题,我在 Google 中找不到解决方案。我只为客户端使用 Nuxt。该 API 在 express 中是完全独立的,并且可以与现有的 VueJS 站点一起使用。

在 Nuxt 中,我现在使用 Auth 模块向我的 express Server/Api 发送带有用户名和密码的请求。Api 接收数据、检查数据并在 MongoDB 中找到帐户。这完全可以正常工作。或者我认为应该的。现在我获取用户对象并从中生成 jwt。我可以调试到这里的所有东西并且它可以工作。现在我可能只是不知道如何继续调试它。我将带有 res.json(user, token) 的答案发送回 Nuxt 客户端(代码如下)。正如我所说,在我当前的 VueJS 页面中,我也可以处理这个问题。同样在 Nuxt 页面中,我在开发控制台中看到了答案,据我所知,答案很合适。

现在一些代码。express Api上的登录部分:

    const User = require('../models/User')
    const jwt = require('jsonwebtoken')
    const config = require('../config/config')

    功能 jwtSignUser(用户){
        常量 ONE_YEAR = 60 * 60 * 24 * 365
        返回 jwt.sign(user,config.authentication.jwtSecret, {
            expiresIn: ONE_YEAR
        })
    }
    模块.exports = {
        异步登录 (req, res){
            控制台.log(req.body)
            尝试{
                const {用户名,密码} = req.body
                const user = await User.findOne({
                    用户名:用户名
                })

                如果(!用户){
                    返回 res.status(403).send({
                        错误:`登录信息不正确。`
                    })
                }

                const isPasswordValid = 等待用户.comparePassword(密码)
                如果(!isPasswordValid){
                    返回 res.status(403).send({
                        错误:`登录信息不正确。`
                    })
                }

                常量 userJson = user.toJSON()
                res.json({
                    用户:userJson,
                    令牌:jwtSignUser(userJson)
                })

            } 捕捉(错误){
                控制台日志(错误)
                res.status(500).send({
                    错误:`尝试登录时发生错误。`
                })
            }
        }
    }

nuxt.config.js:

    授权:{
        策略:{
          当地的: {
            端点:{
              登录:{url:'/login',方法:'post'},
              用户:{url:'/user',方法:'get'},
              注销:假,
            }
          }
        },
        重定向:{
          登录:'/个人资料',
          登出: '/',
          用户资料',
          打回来:'/'
        }
      }

甚至尝试了几乎任何可能的“propertyName”。

最后但并非最不重要的一点是我的 login.vue 上的方法:


    异步登录(){
          尝试 {
            console.log('正在登录...')
            等待 this.$auth.loginWith('local', {
              数据: {
                “用户名”:this.username,
                “密码”:this.password
              }
            }).catch(e => {
              console.log('登录失败');
            })
            if (this.$auth.loggedIn) {
              console.log('登录成功');
            }
          }抓住(e){        
            console.log('用户名或密码错误');
            console.log('错误:', e);
          }
        }

我在这里真的不明白......我总是在控制台中显示“登录......”。没有任何错误消息。

每次我提出请求(按登录按钮)时,我都会在 Chrome 开发工具的“网络”标签中获得 4 个新条目。两次“登录”,然后直接两次“用户”。

第一个“登录”条目如下(在通用标题中):

请求网址:http://localhost:3001/login
请求方法:选项
状态码:204 无内容
远程地址:[::1]:3001
推荐人政策:降级时无推荐人

第一个“用户”条目:

请求网址:http://localhost:3001/user
请求方法:选项
状态码:204 无内容
远程地址:[::1]:3001
推荐人政策:降级时无推荐人

两者都没有任何回应。

第二个登录条目:

请求网址:http://localhost:3001/login
请求方法:POST
状态码:200 OK
远程地址:[::1]:3001
推荐人政策:降级时无推荐人

响应是带有令牌和用户对象的对象。

第二个用户条目:

请求网址:http://localhost:3001/user
请求方法:GET
状态码:200 OK
远程地址:[::1]:3001
推荐人政策:降级时无推荐人

响应是用户对象。

我认为登录应该只有登录请求是相关的,还是我错了?并且用户请求有效,因为客户端已请求用户路由和用户路由,始终在我的 Express API 中使用实际用户对象发送答案。

因为我认为,问题出在登录响应中?这里有一些来自 Chrome 开发工具中网络选项卡的屏幕截图,其中包含登录请求/响应。

第一次登录请求没有响应
第二次登录请求
对第二次登录请求的响应

我必须对我的 Vuex 商店做点什么吗?在使用 google 时,我从未在使用 Auth 模块的示例中找到任何已配置的 Vuex 商店,所以我认为我不必在此处进行任何更改。

尝试登录但未成功后,这就是我的 Vuex 商店(Chrome 中的 Vue 开发工具):

{"navbar":false,"token":null,"user":null,"isUserLoggedIn":false,"access":false,"auth":{"user":"__vue_devtool_undefined__","loggedIn":false, “策略”:“本地”,“忙碌”:假},“feedType”:“流行”}

我还为我的实际 VueJS 站点使用了一些逻辑。当身份验证模块工作时,我将删除它。

@imreBoersma 提问:我在 Express 上的 /user 端点看起来像:

    app.get('/用户',
            已认证,
            用户控制器.getUser)

我首先检查用户是否经过身份验证:

    const 护照 = 要求('护照')

    module.exports = function (req, res, next) {
        passport.authenticate('jwt',功能(错误,用户){
            如果(错误 || !用户){
                res.status(403).send({
                    错误:“您无权执行此操作。”
                })
            } 别的 {
                req.user = 用户
                下一个()
            }
        })(req, res, next)
    }

之后,我在 MongoDB 中搜索用户文档并将文档发送给客户端:

    const User = require('../models/User')

    模块.exports = {
        [...]
        getUser (req, res) {
            User.findById(req.user._id, function (error, user){
                if (error) { console.error(error); }
                res.send(用户)
            })
        }
        [...]

    }

随时询问更多信息。

标签: expressauthenticationjwtnuxt.jsbearer-token

解决方案


我想我可以回答我自己的问题。

我一直在搜索有关我的 api 响应的错误。问题是"propertyName"nuxt.config.js 中的用户端点。

它设置"user"为默认值。当我将它设置为"propertyName: false",比一切正常时。

 auth: {
    strategies: {
      local: {
        endpoints: {
          login: {url: '/login', method: 'post', propertyName: 'token' },
          user: {url: '/user', method: 'get', propertyName: false },
          logout: false,
        }
      }
    }
  },

推荐阅读