提问者:小点点

如何用Nuxt身份验证模块在Vuex中保存JWT令牌?


我目前正在尝试用VueJS将一个VueJS页面转换为NuxtJS。不幸的是,我有一些问题与认证的用户,我不能找到解决方案在谷歌。我只对客户使用Nuxt。API在express中是完全独立的,并且与现有的VueJS站点一起工作。

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

现在有些代码。express API上的登录部分:


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

    function jwtSignUser(user){
        const ONE_YEAR = 60 * 60 * 24 * 365
        return jwt.sign(user,config.authentication.jwtSecret, {
            expiresIn: ONE_YEAR
        })
    }
    module.exports = {
        async login (req, res){
            console.log(req.body)
            try{
                const {username, password} = req.body
                const user = await User.findOne({
                    username: username
                })

                if(!user){
                    return res.status(403).send({
                        error: `The login information was incorrect.`
                    })
                }

                const isPasswordValid = await user.comparePassword(password)
                if(!isPasswordValid) {
                    return res.status(403).send({
                        error: `The login information was incorrect.`
                    })
                }

                const userJson = user.toJSON()
                res.json({
                    user: userJson,
                    token: jwtSignUser(userJson)
                })

            } catch (err) {
                console.log(err)
                res.status(500).send({
                    error: `An error has occured trying to log in.`
                })
            }
        }
    }

nuxt.config.js:


    auth: {
        strategies: {
          local: {
            endpoints: {
              login: {url: '/login', method: 'post' },
              user: {url: '/user', method: 'get' },
              logout: false,
            }
          }
        },
        redirect: {
          login: '/profile',
          logout: '/',
          user: '/profile',
          callback:'/'
        }
      }

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

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



    async login() {
          try {
            console.log('Logging in...')
            await this.$auth.loginWith('local', {
              data: {
                "username": this.username,
                "password": this.password
              }
            }).catch(e => {
              console.log('Failed Logging In');
            })
            if (this.$auth.loggedIn) {
              console.log('Successfully Logged In');
            }
          }catch (e) {        
            console.log('Username or Password wrong');
            console.log('Error: ', e);
          }
        }

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

每次我提出请求(按登录按钮)时,我都会在Chrome Dev Tools中的“Network”标签中获得4个新条目。两次“登录”,之后直接两次“用户”。

第一个“login”条目如下所示(在一般标题中):

Request URL: http://localhost:3001/login
Request Method: OPTIONS
Status Code: 204 No Content
Remote Address: [::1]:3001
Referrer Policy: no-referrer-when-downgrade

第一个“用户”条目:

Request URL: http://localhost:3001/user
Request Method: OPTIONS
Status Code: 204 No Content
Remote Address: [::1]:3001
Referrer Policy: no-referrer-when-downgrade

都没有任何反应。

第二个登录条目:

Request URL: http://localhost:3001/login
Request Method: POST
Status Code: 200 OK
Remote Address: [::1]:3001
Referrer Policy: no-referrer-when-downgrade

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

第二个用户条目:

Request URL: http://localhost:3001/user
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:3001
Referrer Policy: no-referrer-when-downgrade

而响应就是用户对象。

我想对于登录来说,应该只有登录请求才是相关的,还是我错了?并且用户请求工作是因为客户端请求了用户路由和用户路由,则始终将答案与我的Express API中的实际用户对象一起发送。

因为我觉得,问题出在登录响应上?下面是Chrome Dev Tools中网络选项卡的一些屏幕截图,其中包含登录请求/响应。

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

我得对我的Vuex店做点什么吗?在使用google时,我从未在使用Auth模块的示例中发现任何配置的Vuex存储,所以我认为我不需要在这里更改任何内容。

这是我的Vuex商店(Chrome中的Vue Dev Tools)在尝试登录没有成功之后:

{"navbar":false,"token":null,"user":null,"isUserLoggedIn":false,"access":false,"auth":{"user":"__vue_devtool_undefined__","loggedIn":false,"strategy":"local","busy":false},"feedType":"popular"}

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

由@imreboersma提问:Express上的My/Userendpoint看起来像:


    app.get('/user', 
            isAuthenticated,
            UsersController.getUser)

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


    const passport = require('passport')

    module.exports = function (req, res, next) {
        passport.authenticate('jwt', function (err, user) {
            if(err || !user) {
                res.status(403).send({
                    error: 'You are not authorized to do this.'
                })
            } else {
                req.user = user
                next()
            }
        })(req, res, next)
    }

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


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

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

    }

请随时询问更多信息。


共1个答案

匿名用户

我想我能回答我自己的问题。

我整个时间都在搜索一个关于我的api响应的错误。问题是nuxt.config.js中用户端点上的“propertyname”

默认设置为“user”。当我将其设置为“propertyName:false”时,就会像它应该的那样工作。

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