# 🏅 Day 26 - bcrypt.js 密碼加解密
### 密碼加密
使用 bcrypt.js 的 `hash()` 以**非同步**的方式將密碼加密
```javascript
bcrypt.hash(password, 12);
// 第一個參數是要做雜湊加密的字串,第二個參數是要加鹽的字串長度
```
> 補充:
> [雜湊(Hash function)](https://zh.wikipedia.org/zh-tw/%E6%95%A3%E5%88%97%E5%87%BD%E6%95%B8)為一種演算法,會將資料打亂建立雜湊值,雜湊值具有「不可逆」的性質(由此值回推原本的值非常困難),因此常用於密碼加密
> [鹽(Salt)](https://zh.wikipedia.org/zh-tw/%E7%9B%90_(%E5%AF%86%E7%A0%81%E5%AD%A6))在密碼學中,是指在雜湊之前將雜湊內容(例如:密碼)的任意固定位置插入特定的字串。這個在雜湊中加入字串的方式稱為「加鹽」
### 密碼解密
密碼加密後,未來需要驗證是否為該註冊帳號就需以 `compare()` 將密碼與加密後的字串進行比對
```javascript
bcrypt.compare(password, user.password);
// 第一個參數是接收到的密碼,第二個參數是由資料庫找出的該 user 的密碼,為雜湊加密的字串
```
### 參考資源
- [bcrypt.js - hash](https://github.com/dcodeIO/bcrypt.js#hashs-salt-callback-progresscallback)
- [bcryptjs - compare](https://github.com/dcodeIO/bcrypt.js#compares-hash-callback-progresscallback)
題目
---
延續前一天 Day25 解答,運用 bcrypt.js 將使用者註冊輸入的密碼加密後再新增至 User 內
```javascript=
router.post('/sign_up', handleErrorAsync(async (req, res, next) => {
let { name, email, password } = req.body;
// 加入驗證,確保使用者註冊資料符合格式
// 三個欄位皆必填
if (!name || !email || !password) {
return next(appError(400, '請確保所有欄位皆填寫', next));
}
// 暱稱 name 長度需至少 2 個字元以上
if (!validator.isLength(name, { min: 2 })) {
return next(appError(400, '暱稱需至少 2 個字元以上', next));
}
// 信箱 email 格式正確
if (!validator.isEmail(email)) {
return next(appError(400, 'Email 格式錯誤', next));
}
// 密碼 password 長度至少 8 碼以上
if (!validator.isLength(password, { min: 8 })) {
return next(appError(400, '密碼需至少 8 碼以上', next));
}
// 將密碼 password 加密
...
const newUser = await User.create({
email,
password,
name
});
res.status(200).json({
status: 'success',
data: newUser
});
}));
```
## 回報流程
將答案寫在 CodePen 並複製 CodePen 連結貼至底下回報就算完成了喔!
解答位置請參考下圖(需打開程式碼的部分觀看)

<!-- 解答:
```javascript=
router.post('/sign_up', handleErrorAsync(async (req, res, next) => {
let { name, email, password } = req.body;
// 加入驗證,確保使用者註冊資料符合格式
// 三個欄位皆必填
if (!name || !email || !password) {
return next(appError(400, '請確保所有欄位皆填寫', next));
}
// 暱稱 name 長度需至少 2 個字元以上
if (!validator.isLength(name, { min: 2 })) {
return next(appError(400, '暱稱需至少 2 個字元以上', next));
}
// 信箱 email 格式正確
if (!validator.isEmail(email)) {
return next(appError(400, 'Email 格式錯誤', next));
}
// 密碼 password 長度至少 8 碼以上
if (!validator.isLength(password, { min: 8 })) {
return next(appError(400, '密碼需至少 8 碼以上', next));
}
// 將密碼 password 加密
password = await bcrypt.hash(password, 12);
const newUser = await User.create({
email,
password,
name
});
res.status(200).json({
status: 'success',
data: newUser
});
}));
```
-->
回報區
---
<!--
將答案貼至下方表格內,格式:
| Discord 暱稱 | [CodePen](連結) |
-->
| Discord | CodePen / 答案 |
|:-------------:|:-----------------:|
| xxx | [CodePen]() |
| 2魚 | [CodePen](https://codepen.io/ijrekmsn-the-sans/pen/bGJPWvr) |
| 苡安 | [hackmd](https://hackmd.io/@L7K9-66lSeagS28AP0_GjQ/SkLb-otGA) |
|Lobinda|[HackMD](https://hackmd.io/@Lobinda/r1kFviFfC)|
|jenny7532|[CodePen](https://codepen.io/wei-chen-wu/pen/dyEyPrJ)|
|wei|[CodePen](https://hackmd.io/@xu7yoa5cSsqaron7h9XhUw/H1Etm-cz0)|
|william_hsu|[CodePen](https://codepen.io/william8815/pen/jOoOMOe)|
|Chia Pin|[CodePen](https://codepen.io/joker-cat/pen/OJYJmjK)|
| Hank |[CodePen](https://codepen.io/tw1720/pen/dyEyooe)|
| william威良 |[CodePen](https://codepen.io/snowman12320/pen/YzbzePL?editors=1010)|
| Aida |[CodePen](https://codepen.io/ada23410/pen/qBGBxap)|
| runweiting |[CodePen](https://codepen.io/weiting14/pen/oNRXXKy)|
| ej_chuang |[CodePen](https://codepen.io/EJChuang/pen/vYwOMgN)|
| Tiya |[CodePen](https://codepen.io/Tiya_blank/pen/rNbQPbY)|
| zaoannihao | [CodePen](https://codepen.io/ckhwdvrx-the-solid/pen/jOobgza)|
| Mei | [CodePen](https://codepen.io/l_umei/pen/OJYMwKL)|
| Fabio20 | [CodePen](https://codepen.io/fabio7621/pen/yLWVOOg) |