如何使用 Nuxt Auth 模块在 Vuex 中保存 JWT 令牌? [英] How to save JWT Token in Vuex with Nuxt Auth Module?

查看:17
本文介绍了如何使用 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.bodyconst 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 中搜索 User 文档并将文档发送给客户端:

<上一页>const User = require('../models/User')模块.exports = {[...]getUser (req, res) {User.findById(req.user._id, function (error, user){if (error) { console.error(error);}res.send(用户)})}[...]}

请随时询问更多信息.

解决方案

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

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

默认设置为 "user".当我将其设置为 "propertyName: false", 时,一切都会正常运行.

 认证:{策略:{当地的: {端点:{登录:{url:'/login',方法:'post',propertyName:'token'},用户:{url:'/user',方法:'get',propertyName:false},注销:假,}}}},

I am currently trying to convert a VueJS page to NuxtJS with VueJS. Unfortunately I have some problems with authenticating the user and I can't find a solution in Google. I only use Nuxt for the client. The API is completely separate in express and works with the existing VueJS site.

In Nuxt I send now with the Auth module a request with username and password to my express Server/Api. The Api receives the data, checks it, and finds the account in MongoDB. This works exactly as it should. Or as I think it should. Now I take the user object and generate the jwt from it. I can debug everything up to here and it works. Now I probably just don't know how to keep debugging it. I send an answer with res.json(user, token) back to the Nuxt client (code follows below). As I said, in my current VueJS page I can handle this as well. Also in the Nuxt page I see the answer in the dev console and to my knowledge the answer fits.

Now some code. The login part on the 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:'/'
        }
      }

even tried it with nearly any possible "propertyName".

and, last but not least, the method on my 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);
          }
        }

What I really don't understand here... I always get "Loggin in..." displayed in the console. None of the error messages.

I get 4 new entries in the "Network" Tag in Chrome Dev Tools every time I make a request (press the Login Button). Two times "login" and directly afterwards two times "user".

The first "login" entry is as follow (in the General Headers):

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

The first "user" entry:

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

Both without any Response.

The second login entry:

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

and the Response is the object with the token and the user object.

The second user entry:

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

and the Response is the user object.

I think for the login should only the login request be relevant, or I'm wrong? And the user request works because the client has asked for the user route and the user route, always send the answer with the actual user object in my Express API.

Because I think, the problem is in the login response? Here some screenshots from the Network Tab in Chrome Dev Tools with the Request/Response for login.

First login request without response
Second login request
Response to second login request

Do I have to do something with my Vuex Store? I never found any configured Vuex Stores in examples for using the Auth Module while using google so I thougt I do not have to change here anything.

Thats my Vuex Store (Vue Dev Tools in Chrome) after trying to login without success:

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

There is also some logic I use for my actual VueJS site. I will remove that when the Auth Module is working.

Asked by @imreBoersma : My /user endpoint on Express looks like:


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

I first check if the User is authenticated:


    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)
    }

After that I search the User document in MongoDB and send the document to the client:


    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)
            })
        }
        [...]

    }

Feel free to ask for more information.

解决方案

I think I can answer my own question.

I searched the whole time for an error regarding to my api response. The problem was the "propertyName" on user endpoint in the nuxt.config.js.

It is set to "user" as default. When I set it to "propertyName: false", than everything works as it should.

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

这篇关于如何使用 Nuxt Auth 模块在 Vuex 中保存 JWT 令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆