---
# System prepended metadata

title: "\U0001F3C5 Day 32 - JWT 驗證"
tags: [2025 Node.js 後端工程師培訓營]

---

# 🏅 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)|