Какие данные необходимо записывать в jwt (node.js + mongo)?

Для генерирования токена использую
jwt     = require('jsonwebtoken');
/* далее какой-то код */

//функция для создания токена
function createToken(user) {
  return jwt.sign(user, config.secret, { expiresIn: 60*60*5 });
}

/* далее какой-то код */

//после регистрации/авторизации ( в случае успеха) вызывается функция для создания токена
createToken(user);


Хотелось бы узнать лучшую практику, какие данные необходимо передавать в функцию для создания токена.
Будет ли это, к примеру, логин (John) и id( ObjectId("5821d94dbb021a1360582da3") в случае с MongoDB)?
И, сюда же, думаю, будет актуален вопрос:
После того, как у меня в токене будет храниться какая-то информация, позволяющая инициализировать пользователя, я могу вытаскивать его данные из БД. Правильно ли это, инициализировать пользователя на основе jwt? Для инициализации использую либу express-jwt, которая в случае успеха устанавливает req.user?
Спасибо.
  • Вопрос задан
  • 1009 просмотров
Решения вопроса 1
maxfarseer
@maxfarseer
https://maxpfrontend.ru, обучаю реакту и компании
Логин класть в токен не нужно. В токене не должно быть "личной информации", а вот ObjectId уже можно. Это не подходит "под личную", так как по 5821d94dbb021a1360582da3 нельзя узнать что-то о пользователе, если у вас не своровали базу (могу ошибаться).

Приведу на всякий случай полный код роута с выдачей токена, если вам не особо пригодится, так может кто поругает, так как в бэкэнде не силен. Код не на промисах, а на коллбэках (как в древние времена). Это плохо. С помощью промисов будет "более плоский" и удобный в поддержке код.

const express = require('express')
const router = express.Router()
const User = require('../models/user')
const v4 = require('node-uuid').v4
const jwt = require('jsonwebtoken')

router.post('/signup', (req, res, next) => {

  req.check('email', 'Please enter a valid email').len(1).isEmail()
  req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)

  const errors = req.validationErrors()

  if (errors) {
    return res.status(400).json({ errors })
  } else {
    User.hashPassword(req.body.password, (err, passwordHash) => {
      if (err) {
        return res.status(400).json({ error: err.message })
      }

      const user = new User({
        name: req.body.name,
        nickname: req.body.nickname,
        email: req.body.email,
        password: req.body.password,
      })

      user.passwordHash = passwordHash
      user.save((err, item) => {
        if (err) {
          return res.status(400).json({ error: err.message })
        }
        const payload = {
          _id: item._id,
          iss: 'http://localhost:3000',
          permissions: 'poll',
        }
        const options = {
          expiresIn: '7d',
          jwtid: v4(),
        }
        const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
        jwt.sign(payload, secret, options, (err, token) => {
          return res.json({ data: token })
        })
      })
    })
  }
})

router.post('/signin', (req, res, next) => {

  req.check('email', 'Please enter a valid email').len(1).isEmail()
  req.check('password', 'Please enter a password with a length between 4 and 34 digits').len(4, 34)

  const errors = req.validationErrors()
  const password = req.body.password

  if (errors) {
    return res.status(400).json({ errors })
  } else {
    User.findOne({ email: req.body.email }, (err, user) => {
      if (err) {
        return res.status(400).json({ error: err.message })
      }
      if (!user) {
        return res.status(400).json({ error: 'User not found' })
      }
      User.comparePasswordAndHash(password, user.passwordHash, (err, areEqual) => {
        if (err) {
          return res.status(400).json({ error: err.message })
        }
        if (!areEqual) {
          return res.status(400).json({ error: 'Wrong password' })
        }
        const payload = {
          _id: user._id,
          iss: 'http://localhost:3000',
          permissions: 'poll',
        }
        const options = {
          expiresIn: '7d',
          jwtid: v4(),
        }
        const secret = new Buffer(process.env.AUTH0_CLIENT_SECRET, 'base64')
        jwt.sign(payload, secret, options, (err, token) => {
          return res.json({ data: token })
        })
      })
    })
  }
})

module.exports = router;


В дальнейшем, кусочек payload:
const payload = {
          _id: item._id,
          iss: 'http://localhost:3000',
          permissions: 'poll',
        }

можно "декодировать" прямо на клиенте, что очень удобно.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы