Аутентификация токена — JWT

Когда мы используем jsonwebtoken в Node, мы подписываем определенный токен для пользователя и отправляем его обратно. Однако, когда мы проверяем токен, когда пользователь отправляет его в заголовке (Authentication: <token>), как jwt узнает, что этот токен, который он проверяет, предназначен для этого конкретного пользователя, а не для какого-то другого пользователя, который также отправил запрос в то же время? Он хранит токен где-то внутри?


person xyz6675    schedule 06.06.2020    source источник


Ответы (4)


Во время входа в систему вы подписываете токен, где полезная нагрузка — это userId, которое представляет собой не что иное, как поле _id в запрашиваемом объекте пользователя.

loginUser: async (req, res, next) => {
    try {
      const { email, password } = req.body
      const user = await User.findOne({ email })
      const token = auth.signToken({ userId: user._id })
      res.status(200).json({ user, token })
    } catch (error) {
      return next(error)
    }
  }

auth.js

function signToken(payload) {
  return jwt.sign(payload, JWTSECRET)
}

function verifyToken(req, res, next) {
  const token = req.headers.Authorization || req.headers.authorization || ""
  if (!token) {
    return res.status(403).json({ error: "Not authorized" })
  }

  jwt.verify(token,JWTSECRET, (err, decodedObj) => {
    if (err) {
      return res.status(403).json({ error: "Not authorized" })
    }

    req.user = decodedObj
    next()
  })
}

module.exports = { signToken, verifyToken }


В обратном вызове jwt.verify вы получаете decodedObj, что-то вроде:

{ userId: '5edb3ae6d6b129183c1393bc', iat: 1591425786 }

где iat — время выпуска jwt.


 req.user = decodedObj

Здесь мы «прикрепляем» декодированные данные к пользовательскому объекту, чтобы при запросе защищенного маршрута мы могли получить userId из объекта запроса, например req.user.userId, а затем запросить его из базы данных.


Когда вы подписываете токен, вы предоставляете полезную нагрузку, которая может быть userId и секретом. Итак, токен подписан. После этого вам необходимо проверить токен на случай, если вы попытаетесь получить доступ к какой-либо защищенной странице, для которой требуется токен.

Итак, когда вы отправляете запрос на этот защищенный маршрут, например:

   router.get("/me", auth.verifyToken, usersController.identifyUser)

где identifyUser — это функция контроллера, которая просто идентифицирует вошедшего в систему пользователя, проверяя userId (помните, что объект пользователя содержит декодированные данные объекта).


как jwt узнает, что тот токен, который он проверяет, предназначен для этого конкретного пользователя, а не для какого-то другого пользователя, который также отправил запрос в то же время? Он хранит токен где-то внутри?

Это из-за полезной нагрузки, которую вы даете, которая уникальна для пользователя.

person metalHeadDev    schedule 06.06.2020
comment
Итак, мне нужно вручную проверить, находится ли пользователь в базе данных после verifyToken? Также не могли бы вы подробнее рассказать об этой функции контроллера? - person xyz6675; 06.06.2020
comment
Извини, что ты имеешь ввиду? Я не понимаю. - person metalHeadDev; 06.06.2020

  1. токен больше всего хранится в клиенте
  2. когда токен успешно проверен, мы получим некоторую информацию о пользователе и т. д. идентификатор учетной записи, поэтому мы можем использовать идентификатор учетной записи, чтобы найти дополнительную информацию о пользователе в базе данных и проверить, что использование действительно существует.

может быть, это полезно для вас?

person chenc    schedule 06.06.2020

Обычно вы подписываете токен идентификатором пользователя при его отправке с сервера. Поэтому, когда клиент затем отправляет обратно этот токен, вы декодируете его, и он возвращает вам идентификатор. Который вы затем используете, чтобы найти пользователя в базе данных

person Adil Khan    schedule 06.06.2020

Токен Authentication хранится на сервере аутентификации, поэтому, когда вы отправляете токен Authentication в заголовке запроса, сервер аутентификации аутентифицирует вашего клиента.

После аутентификации на Сервере аутентификации клиент теперь может передавать JWT для выполнения вызовов API к Серверу приложений. Поскольку клиенту разрешено выполнять вызовы API, Сервер приложений может проверить маркер JWT, отправленный клиентом, и обработать вызов API.

Обратите внимание, что для выполнения вызовов API клиент должен отправлять Authorization: Bearer <token> для каждого вызова API, который хранится на сервере (он же сервер авторизации).

person Ayman Arif    schedule 06.06.2020