Когда мы используем jsonwebtoken в Node, мы подписываем определенный токен для пользователя и отправляем его обратно. Однако, когда мы проверяем токен, когда пользователь отправляет его в заголовке (Authentication: <token>)
, как jwt узнает, что этот токен, который он проверяет, предназначен для этого конкретного пользователя, а не для какого-то другого пользователя, который также отправил запрос в то же время? Он хранит токен где-то внутри?
Аутентификация токена — JWT
Ответы (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 узнает, что тот токен, который он проверяет, предназначен для этого конкретного пользователя, а не для какого-то другого пользователя, который также отправил запрос в то же время? Он хранит токен где-то внутри?
Это из-за полезной нагрузки, которую вы даете, которая уникальна для пользователя.
- токен больше всего хранится в клиенте
- когда токен успешно проверен, мы получим некоторую информацию о пользователе и т. д. идентификатор учетной записи, поэтому мы можем использовать идентификатор учетной записи, чтобы найти дополнительную информацию о пользователе в базе данных и проверить, что использование действительно существует.
может быть, это полезно для вас?
Обычно вы подписываете токен идентификатором пользователя при его отправке с сервера. Поэтому, когда клиент затем отправляет обратно этот токен, вы декодируете его, и он возвращает вам идентификатор. Который вы затем используете, чтобы найти пользователя в базе данных
Токен Authentication
хранится на сервере аутентификации, поэтому, когда вы отправляете токен Authentication
в заголовке запроса, сервер аутентификации аутентифицирует вашего клиента.
После аутентификации на Сервере аутентификации клиент теперь может передавать JWT для выполнения вызовов API к Серверу приложений. Поскольку клиенту разрешено выполнять вызовы API, Сервер приложений может проверить маркер JWT, отправленный клиентом, и обработать вызов API.
Обратите внимание, что для выполнения вызовов API клиент должен отправлять Authorization: Bearer <token>
для каждого вызова API, который хранится на сервере (он же сервер авторизации).