--- tags: Node.js 直播班 - 2023 春季班 --- # 🏅 Day 28 - 登入功能 **密碼解密** 若使用者成功註冊,密碼被加密後,未來需要驗證是否為該註冊帳號可使用 `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.) ### 題目 - 實做登入功能 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/vftL5i0.png) <!-- 解答: 範例參考 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); })) ``` --> 回報區 --- | 報數 | 組別/Discord 名字 | Codepen/HackMD/其他回饋 | |:----:|:-----------------------:|:-------------------------------------------------------------------------:| | 1 | 中 4 組 / jimkk159 | [HackMD - Day 28](https://hackmd.io/_BZpdwLMTNStZZky79hUqg) | | 2 | 北 13 組 / Louisa | [GitHub - Day 28](https://github.com/louisa0416/NodejsEnterpriseClass/tree/master/daily-task/day28) | | 3 | 北 13 組 / 文文 | [GitHub - Day 28](https://github.com/chiawen81/nodeJS_DailyTasks_d20/tree/b7a751530ff1965f63a9eb2654f355fb9edfa06c) | | 4 | 南 1 組 / hiYifang | [HackMD - Day 28](https://hackmd.io/@gPeowpvtQX2Om6AmD-s3xw/S1WEL_yPc) |