# 🏅 Day 33 - JWT 驗證 middleware 我們可以將 isAuth 作為 middlware,將需要登入後才能進入、操作的頁面或功能都帶入 isAuth middlware,確認使用者身份後再繼續執行 題目 --- 根據需求,補上 `...` 的部分完整程式碼 1. 優化 `isAuth`,確認 token 存在並確認是否為 Bearer 開頭字串。 若符合此條件則取出 JWT 字串,若未成功取得 JWT,表示使用者可能尚未登入,需回傳 401 錯誤與錯誤訊息 `'使用者尚未登入!'` ```javascript= const isAuth = handleErrorAsync(async (req, res, next) => { // 確認 token 是否存在並取出 token let token; if ( req.headers.authorization && req.headers.authorization....('...') ) { token = req.headers.authorization.split(' ')[1]; } // token 不存在,回傳錯誤訊息 if (!token) { return appError(...); } // 驗證 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(); }); ``` 2. 設計取得個人資料路由 `GET /users/profile`,加入 isAuth middleware,當 request 帶上的 token 驗證通過,就將取出的 user 資料回傳給 client `routes/users.js` ```javascript= router.get('/profile', ..., handleErrorAsync(async (req, res, next) =>{ res.status(200).json({ status: 'success', user: ... }); })) ``` ## 回報流程 將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔! 解答位置請參考下圖(需打開程式碼的部分觀看) ![](https://i.imgur.com/vftL5i0.png) <!-- 解答: 1. isAuth ```javascript= const isAuth = handleErrorAsync(async (req, res, next) => { // 確認 token 是否存在並取出 token let token; if ( req.headers.authorization && req.headers.authorization.startsWith('Bearer') ) { token = req.headers.authorization.split(' ')[1]; } // token 不存在,回傳錯誤訊息 if (!token) { return appError(401, '使用者尚未登入!', next); } // 驗證 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(); }); ``` 2. routes/users.js ```javascript= router.get('/profile', isAuth, handleErrorAsync(async (req, res, next) =>{ res.status(200).json({ status: 'success', user: req.user }); })) ``` --> 回報區 --- <!-- 將答案貼至下方表格內,格式: | Discord 暱稱 | [CodePen](連結) | --> | Discord | CodePen / 答案 | |:-------------:|:-----------------:| |Tau| [CodePen](https://codepen.io/Tau-Hsu/pen/RNwGEya?editors=0010) | | poyi | [CodePen](https://codepen.io/poyi-the-flexboxer/pen/XJWjwzb?editors=1010) | | adengg | [CodePen](https://codepen.io/Osases/pen/OPJbLww?editors=0010) | |janetlai|[CodePen](https://codepen.io/eiddkqxz-the-builder/pen/VYwmbwa?editors=0010) |HarryKuo|[CodePen](https://codepen.io/harry_kuo/pen/XJWNaPy?editors=0010)| |helena|[CodePen](https://codepen.io/helena27/pen/XJWgpgw)| |hsin yu|[CodePen](https://codepen.io/tina2793778/pen/Byambrj)|