# 🏅 Day 32 - JWT 驗證 當需要登入才能造訪頁面或操作功能, client 端發出請求時就會需要在 headers 的 Authorization(`req.headers.authorization`)帶上 JWT(`Bearer xxxxxx`),並經由後端驗證 而後端驗證的部分會使用 jsonwebtoken 套件的 `vertify()` 方法 ```javascript const jwt = require('jsonwebtoken'); jwt.verify(token, secretOrPublicKey, [options, callback]); ``` - token 為使用者夾帶需驗證的字串 - secretOrPublicKey 需帶入先前的環境變數 `process.env.JWT_SECRET` 因驗證 token 需要時間,所以需要使用非同步的方式來處理回傳的驗證結果 範例: ```javascript= const decoded = await new Promise((resolve,reject) => { jwt.verify(token, process.env.JWT_SECRET, (err, payload) => { if (err) { reject(err) } else { resolve(payload) } }); }); ``` ### 參考資源 - [JWT 流程圖](https://whimsical.com/jwt-UKUY1rj1vfoN6uyic7e4Sm) - [jwt.verify()](https://github.com/auth0/node-jsonwebtoken#jwtverifytoken-secretorpublickey-options-callback) 題目 --- 當使用者進入個人資料頁面、追蹤頁面等,會需要登入並取得 token。進入頁面發出請求時會夾帶 token,我們需要驗證帶入的 token 是否正確,確保使用者有正確登入。 以下為驗證 token 的函式,請補上 `...` 的部分完整下方程式碼 ```javascript= const isAuth = handleErrorAsync(async (req, res, next) => { // 帶入使用者發出請求時夾帶的 token(取出 Bearer 後方字串) let token = req.headers.authorization....; // 驗證 token 正確性 const decoded = await new Promise((resolve,reject) => { ... }); // 在資料庫尋找對應 id 的使用者 const currentUser = await User.findById(/* 帶入驗證 token 解碼後取得的使用者 id */); // 在 req 物件加入 user 欄位,並由 next() 帶到 handleErrorAsync(async(req,res,next)=>{...}) req.user = currentUser; next(); }); ``` ## 回報流程 將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) <!-- 解答: ```javascript= const isAuth = handleErrorAsync(async (req, res, next) => { // 帶入使用者發出請求時夾帶的 token(取出 Bearer 後方字串) let token = req.headers.authorization.split(' ')[1]; // 驗證 token 正確性 const decoded = await new Promise((resolve,reject) => { jwt.verify(token, process.env.JWT_SECRET, (err, payload) => { if (err) { reject(err) } else { resolve(payload) } }); }); // 在資料庫尋找對應 id 的使用者 const currentUser = await User.findById(decoded.id); // 在 req 物件加入 user 欄位,並由 next() 帶到 handleErrorAsync(async(req,res,next)=>{...}) req.user = currentUser; next(); }); ``` --> 回報區 --- <!-- 將答案貼至下方表格內,格式: | Discord 暱稱 | [CodePen](連結) | --> | Discord | CodePen / 答案 | |:-------------:|:-----------------:| |Tau| [CodePen](https://codepen.io/Tau-Hsu/pen/dPypMLm?editors=0010) | | poyi | [CodePen](https://codepen.io/poyi-the-flexboxer/pen/mydrOdM?editors=0010) | |janetlai|[CodePen](https://codepen.io/eiddkqxz-the-builder/pen/bNGwqYo) |adengg|[CodePen](https://codepen.io/Osases/pen/VYwKWYd?editors=0010) |HarryKuo|[CodePen](https://codepen.io/harry_kuo/pen/MYWbvQG?editors=0010)| |sui_hsilan|[CodePen](https://codepen.io/suihsilan/pen/NPWpGRE?editors=0010)| |helena|[CodePen](https://codepen.io/helena27/pen/yyLXgMR)| |hsin yu|[CodePen](https://codepen.io/tina2793778/pen/Byambmo)|