# 🏅 Day 29 - 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 / 答案 | |:-------------:|:-----------------:| | xxx | [CodePen]() | | 苡安 | [hackmd](https://hackmd.io/@L7K9-66lSeagS28AP0_GjQ/SkQNdNgQR) | | jenny7532 | [CodePen](https://codepen.io/wei-chen-wu/pen/ExzjVVo) | | runweiting | [CodePen](https://codepen.io/weiting14/pen/jOoPbLy) | |Lobinda|[HackMD](https://hackmd.io/@Lobinda/rk_uMOeXA)| |wei|[HackMD](https://hackmd.io/@xu7yoa5cSsqaron7h9XhUw/H1YoauemC)| | Aida |[CodePen](https://codepen.io/ada23410/pen/JjqddBr?editors=0010)| | william_hsu |[CodePen](https://codepen.io/william8815/pen/wvbaojZ)| | william威良 |[CodePen](https://codepen.io/snowman12320/pen/zYQGNXm)| | Chia Pin |[CodePen](https://codepen.io/joker-cat/pen/VwOLEVX)| | ej_chuang |[CodePen](https://codepen.io/EJChuang/pen/RwmPOJo)| | Tiya |[CodePen](https://codepen.io/Tiya_blank/pen/rNbQPbY)| | Hank |[CodePen](https://codepen.io/tw1720/pen/OJYJVVG)| |zaoannihao|[CodePen](https://codepen.io/ckhwdvrx-the-solid/pen/GRapVyo)| |mei|[CodePen](https://codepen.io/l_umei/pen/RwmGeKX)| | Fabio20 | [CodePen](https://codepen.io/fabio7621/pen/oNRYxdV) |