簡體   English   中英

刷新令牌如何處理 POST 路由

[英]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 結果= 新的訪問和刷新令牌

->並再次使用新的發布請求向原始中間件發布請求?

這里的程序是什么,我找不到任何解決方法。

請記住,我的回答是基於我的經驗。 如果我碰巧在我的方式上犯了錯誤,任何人都可以隨意編輯。

因此,為了處理刷新令牌,我使用這種方式:

  • 當用戶成功登錄后,JWT(包含用戶的auth)和刷新令牌(包含用戶的刷新令牌)將被放置在用戶的cookies中(和你一樣)。
  • 用戶將在您的 web 應用程序中做他/她的事情,直到他/她關閉瀏覽器而不退出。
  • 請記住,JWT 始終有到期日期 - 將記住此到期日期。
  • 在每個請求中,您將發送特定的 JWT(包含用戶的身份驗證)和刷新令牌到您將發出POST請求的中間件。 如果 JWT 已過期,請選擇刷新令牌並調用/refresh-token-result以獲取新令牌。 否則,不要對刷新令牌做任何事情並繼續您的請求。
  • 確保您的/refresh-token-result接受請求令牌。 端點將檢查其有效性並返回一個新的訪問令牌。
  • 如果刷新令牌已過期,請注銷用戶。 這是出於安全原因,這很重要!

哦,當用戶注銷時,請確保您的用戶令牌和用戶的刷新令牌都被正確撤銷,通常通過更改 cookie 值和expiresIn屬性。 對我來說,我通常將兩個 cookie 值都更改為loggedOut ,並將expiresIn設置為 5 秒。

或者,如果您正在使用 React(附加答案),您可以這樣做:

  • 如果用戶訪問您的網站,並且 JWT 到期日期即將到期,您可以簡單地使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM