Как сохранить токен JWT в Vuex с модулем аутентификации Nuxt? - PullRequest
1 голос
/ 04 мая 2019

В настоящее время я пытаюсь преобразовать страницу VueJS в NuxtJS с помощью VueJS.К сожалению, у меня есть некоторые проблемы с аутентификацией пользователя, и я не могу найти решение в Google.Я использую только Nuxt для клиента.API полностью отделен в экспрессе и работает с существующим сайтом VueJS.

В Nuxt теперь я отправляю с модулем Auth запрос с именем пользователя и паролем на мой экспресс-сервер / API.Api получает данные, проверяет их и находит учетную запись в MongoDB.Это работает именно так, как и должно.Или, как я думаю, должно.Теперь я беру пользовательский объект и генерирую из него jwt.Я могу отлаживать все здесь, и это работаетТеперь я, наверное, просто не знаю, как продолжать отлаживать его.Я отправляю ответ с res.json (user, token) обратно клиенту Nuxt (код приведен ниже).Как я уже сказал, на моей текущей странице VueJS я могу справиться и с этим.Также на странице Nuxt я вижу ответ в консоли разработчика и, насколько мне известно, ответ подходит.

Теперь немного кода.Часть входа в экспресс 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);
          }
        }

Что я действительно не понимаю здесь ... Я всегда отображаю "Loggin in ..." в консоли.Ни одно из сообщений об ошибке.

Каждый раз, когда я делаю запрос, я получаю 4 новые записи в теге «Сеть» в Chrome Dev Tools (нажмите кнопку «Вход»).Дважды «войти в систему» ​​и сразу после этого два раза «пользователь».

Первая запись «входа в систему» ​​выглядит следующим образом (в общих заголовках):

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 Store?Я никогда не обнаруживал ни одного сконфигурированного магазина Vuex в примерах использования модуля Auth при использовании Google, так что я не должен ничего менять здесь.

Это мой Vuex Store (Vue Dev Tools в Chrome) после попытки входа в системубез успеха:

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

Существует также некоторая логика, которую я использую для своего настоящего сайта VueJS.Я уберу это, когда модуль Auth работает.

Отвечая на вопрос @imreBoersma: Моя / пользовательская конечная точка в Express выглядит так:


    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 Ответ

0 голосов
/ 05 мая 2019

Я думаю, что могу ответить на свой вопрос.

Я все время искал ошибку относительно моего ответа API. Проблема заключалась в том, что «propertyName» на конечной точке пользователя в nuxt.config.js.

По умолчанию установлено значение «пользователь». Когда я устанавливаю его в «propertyName: false», все работает как надо.

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

},

...