# 🏅 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 連結貼至底下回報就算完成了喔!
解答位置請參考下圖(需打開程式碼的部分觀看)

<!-- 解答:
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)|