[英]Refresh token how to handle POST routing
我是 JWT 和用於用戶驗證和登錄的令牌的新手。 我為 Node JS (NPM) 使用了以下擴展
var jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser')
require('dotenv').config();
// Express ..
我已經有一個登錄名,可以檢查 MongoDB(Node JS 作為服務器)用戶,檢查 email 和密碼,然后設置一個帶有訪問令牌和刷新令牌的 cookie。
我的登錄代碼就像
//create the access token with the shorter lifespan
let accessToken = jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET, {
algorithm: "HS256",
expiresIn: process.env.ACCESS_TOKEN_LIFE
})
//create the refresh token with the longer lifespan
let refreshToken = jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET, {
algorithm: "HS256",
expiresIn: process.env.REFRESH_TOKEN_LIFE
})
//send the access token to the client inside a cookie
res.cookie("_login", accessToken, {secure: true, httpOnly: true})
res.send()
這是刷新令牌帖子的部分
exports.refresh = function (req, res, next){
console.log("Test");
let accessToken = req.cookies._login
if (!accessToken){
return res.status(403).send()
}
let payload
try{
payload = jwt.verify(accessToken, process.env.ACCESS_TOKEN_SECRET)
}
catch(e){
return res.status(401).send()
}
//retrieve the refresh token from the users array
let refreshToken = payload.email.refreshToken
//verify the refresh token
try{
jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET)
}
catch(e){
return res.status(401).send()
}
let newToken = jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET,
{
algorithm: "HS256",
expiresIn: process.env.ACCESS_TOKEN_LIFE
})
res.cookie("_login", newToken, {secure: true, httpOnly: true})
res.send()
我現在的問題是,因為我在很多教程和指南中看到它們也可以通過 POST 使用刷新令牌,我該如何與用戶一起處理它?
客戶端是否會發送 AJAX 或發布到中間件以檢查訪問令牌
-> 如果訪問令牌已過期
--> 代碼自動獲取刷新令牌並發出新的訪問令牌並給出 OK?
或客戶端發送到檢查訪問令牌的中間件
->訪問令牌已過期(結果給用戶)
->客戶端現在將請求發布到 /refresh-token 結果= 新的訪問和刷新令牌
->並再次使用新的發布請求向原始中間件發布請求?
這里的程序是什么,我找不到任何解決方法。
請記住,我的回答是基於我的經驗。 如果我碰巧在我的方式上犯了錯誤,任何人都可以隨意編輯。
因此,為了處理刷新令牌,我使用這種方式:
POST
請求的中間件。 如果 JWT 已過期,請選擇刷新令牌並調用/refresh-token-result
以獲取新令牌。 否則,不要對刷新令牌做任何事情並繼續您的請求。/refresh-token-result
接受請求令牌。 端點將檢查其有效性並返回一個新的訪問令牌。 哦,當用戶注銷時,請確保您的用戶令牌和用戶的刷新令牌都被正確撤銷,通常通過更改 cookie 值和expiresIn
屬性。 對我來說,我通常將兩個 cookie 值都更改為loggedOut
,並將expiresIn
設置為 5 秒。
或者,如果您正在使用 React(附加答案),您可以這樣做:
useEffect()
掛鈎來更新您的訪問令牌。TL;DR:你的第二種方式已經很好了。
編輯:示例偽代碼可以幫助您。 不要馬上復制粘貼它,它很可能不起作用,但它應該讓你大致了解事情是如何工作的。
// middleware.js
const { token, refreshToken } = req.cookies;
// 1. If the token has not expired, call 'next()'
// assume 'isExpired' returns boolean: true or false depending on the state of your token.
if (!token.isExpired()) {
return next();
}
// 2. If the token has expired AND the refreshToken has not expired, issue a new token, THEN call 'next()'
if (token.isExpired() && !refreshToken.isExpired()) {
await issueToken();
return next();
}
// 3. Else, logout the user. I'll keep this one short.
await logoutUser();
res.status(401).json({
status: 'fail',
message: 'Your access has expired! Please log in again!',
});
這是你的 controller。
// controller.js
const getAllComments = async (req, res, next) => {
const comments = await Comment.find();
res.status(200).json({
status: 'success',
data: comments,
});
}
而且,這就是您的路線應該是什么樣子。
// this import might be unresolved - keep in mind!
const middleware = require('./middleware');
const getAllComments = require('./controllers');
router.get('/api/v1/comments/', middleware,
checkToken, getAllComments); // assume checkToken is your function to check for a token's validity.
請記住,我沒有包含錯誤處理以使此示例簡短。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.