--- tags: Node.js 直播班 - 2022 春季班 --- # 🏅 Day 29 ## 登入功能 **密碼解密** 若使用者成功註冊,密碼被加密後,未來需要驗證是否為該註冊帳號可使用 `compare()` 將密碼與加密後的字串進行比對 ```javascript // 尋找資料庫符合接收到的使用者資料,因 password 欄位在 schema 通常設定為不顯示,因此可使用 select() 將密碼顯示出來 const user = await User.findOne({ email }).select('+password'); bcrypt.compare(password, user.password); // 第一個參數是接收到的密碼,第二個參數是由資料庫找出的該 user 的密碼,為雜湊加密的字串 ``` ### 參考資源 [bcryptjs - compare](https://github.com/dcodeIO/bcrypt.js#compares-hash-callback-progresscallback) [mongoose select()](https://mongoosejs.com/docs/api/query.html#:~:text=When%20using%20string%20syntax%2C%20prefixing%20a%20path%20with%20%2D%20will%20flag%20that%20path%20as%20excluded.%20When%20a%20path%20does%20not%20have%20the%20%2D%20prefix%2C%20it%20is%20included.%20Lastly%2C%20if%20a%20path%20is%20prefixed%20with%20%2B%2C%20it%20forces%20inclusion%20of%20the%20path%2C%20which%20is%20useful%20for%20paths%20excluded%20at%20the%20schema%20level.) ### 題目(將答案寫在 GitHub 並提交至回報區) - 實做登入功能 POST `/users/sign_in`,使用 bcryptjs `compare()` 比對密碼是否與資料庫中的密碼符合,並根據結果回饋訊息,若符合則需產生 JWT 給 client - 若找不到符合的使用者資料或密碼比對不正確,都需回饋錯誤訊息 - 將產生 JWT 功能拆出獨立模組 ::: spoiler 回饋訊息範例 ![](https://i.imgur.com/GAWJkNu.png) ![](https://i.imgur.com/EHmLduK.png) ![](https://i.imgur.com/VXAYd2G.png) ::: 回報流程 --- 請同學依照下圖教學觀看解答、回報答案: ![](https://i.imgur.com/QtL8zEW.png) 回報格式:請在「回報區」貼上 CodePen 或 HackMD 連結回報答案 (為了統計人數,請同學依序加上「報數」) <!-- 解答 範例參考 https://github.com/gonsakon/express-week4-sample/blob/week6/routes/users.js ```javascript const generateSendJWT= (user,statusCode,res)=>{ // 產生 JWT token const token = jwt.sign({id:user._id},process.env.JWT_SECRET,{ expiresIn: process.env.JWT_EXPIRES_DAY }); user.password = undefined; res.status(statusCode).json({ status: 'success', user:{ token, name: user.name } }); } router.post('/sign_in', handleErrorAsync(async(req,res,next)=>{ const { email, password } = req.body; if (!email || !password) { return next(appError( 400,'帳號密碼不可為空',next)); } const user = await User.findOne({ email }).select('+password'); console.log(user); if (!user) { return next(appError(400, "帳號或密碼錯誤,請重新輸入!", next)); } const auth = await bcrypt.compare(password, user.password); if(!auth){ return next(appError(400,'您的密碼不正確',next)); } generateSendJWT(user,200,res); })) ``` --> 回報區 --- | 報數 | 組別 / 名字 | codepen / hackMD / 其他回饋 | | ---- | ----------------- | ------------------------------------------------------------- | | 1 | 第五組 / Hazel | [HackMD@Hazel](https://hackmd.io/@hazelwu/day29) | | 2 | 第 14 組|East | [HackMD](https://hackmd.io/_WD3A3xiSraObPxhV-Q9sw) | | 3 | 第 11 組|Han Lai | [HackMD](https://hackmd.io/61g9Dmb5T2uuMj6rD4hTwQ?view) | | 4 | 第 3 組|hiYifang | [HackMD](https://hackmd.io/@gPeowpvtQX2Om6AmD-s3xw/S1WEL_yPc) | | 5 | 第 9 組 / 黃士桓 | [HackMD](https://hackmd.io/UvlyqWbuQdyJLLOrnPacYw) | | 6 | 第 4 組 / 苡安 | [HackMD](https://hackmd.io/vLg0fTZxQkWzuvmq7mlslA) | | 7 |第 9 組 / konstante |[HackMD](https://hackmd.io/5m9D1IUAQeusv5Qh2HJbvg?edit) | | 8 | 第 4 組 / 小宥 | [HackMD](https://hackmd.io/il1PRjCHQQ-VeVbwzArOWw) | | 9 | 第 3 組 / Hobby | [HackMD](https://hackmd.io/@hobbyling/day29) | | 10 | 第 2 組 / joe | [HackMD](https://hackmd.io/uaRTw9c0TgOrADyXMmGL0Q?view#519-jwt-sign_in) | 11 | 第 7 組 / jason06286 | [HackMD](https://hackmd.io/xIetQwQnSs2xYaI_znvvog) | | 12 | 第 12 組 / Jimmy | [HackMD](https://hackmd.io/1T7VCdBKR9iWXCTMWKp1zA) | | 13 | 第2組 / wendy | [HackMD](https://hackmd.io/80FIwll1QUa4u0-WoBv-hQ#20220518)| | 14 | 第16組 / 皓皓 | [HackMD](https://hackmd.io/@cutecat8110/SkQPzcKcc)|