iT邦幫忙

2023 iThome 鐵人賽

DAY 21
0
自我挑戰組

30 天架設 Node.js - Express 框架:快速學習之路系列 第 21

Day 21 - 身分驗證與授權:實作使用者註冊和登入系統(下)

  • 分享至 

  • xImage
  •  

昨天已經完成了我們的註冊 / 登入系統,

但會員資料明碼存在資料庫有點怪怪的 /images/emoticon/emoticon06.gif

今天我們要來介紹怎麼幫密碼加密啦~

介紹加密套件 bcrypt

後端很常與第三方進行資料串接時,會加密後再打 API 過去,

或是像前面提到儲存密碼的時候,需要將密碼加密後再存到資料庫。

這時候就可以使用這個加密套件 bcrypt 啦。

  • 安裝套件
    • 在終端機下 npm install bcrypt 安裝 bcrypt 套件。
  • 使用方式
    • 建立一個 utils 資料夾,專門可以存放一過工具類的方法並在資料夾底下新增一個 passwordUtils.js 資料夾。
    • bcrypt 加解密的方式
      • 加密:

        • 加密需要設定一個 saltRounds 的參數,顧名思義就是要加鹽的次數,如果使用的參數越高,加鹽次數多越安全,但是加密時間也會拉長。
        • 接著使用 bcrypt.hash(密碼,saltRounds) 就會產生一個加延後的密碼囉!
        • 完整可以查看以下程式。
        async function hash(password) {
        	const saltRounds = 10
        	try {
        			const hashedPassword = await bcrypt.hash(password, saltRounds)
        
        			return hashedPassword
        	} catch (err) {
        			throw new Error('Password hashing failed')
        	}
        }
        
      • 解密:

        • 解密的話就相對簡單很多,不必再將加鹽的密碼再變回明碼,只要使用 bcrypt.compare(${密碼},加密後的密碼),套件就能比對是否與密碼相同,結果會回傳一個布林值。

        • 完整可以查看以下程式。

              async function compare(password, hashedPassword) {
                  return await bcrypt.compare(password, hashedPassword)
              }
          

調整程式

  • 先調用我們剛剛寫的 passwordUtils 模組
const passwordUtils = require('../../utils/passwordUtils')
  • 註冊 routes/modules/signIn.js

    • 調整在註冊的 POST 請求中獲取用戶名和密碼時,先加密碼加密後再存到資料庫。

          const hashedPassword = await passwordUtils.hash(password) //使用加密的方法
      
          await user.create({ username: username, password: hashedPassword }, { raw: true }) //儲存加密的密碼
      
    • 所以可以看到我們555帳號的密碼,變成一長串的亂碼了!

      https://ithelp.ithome.com.tw/upload/images/20230915/20162304XZip9lBfC2.png

  • 登入 routes/modules/login.js

    • 調整在登入的 POST 請求中,比對密碼的地方改為使用我們剛剛解碼比對的方法。
        if (username !== userData.username || !await passwordUtils.compare(password, userData.password)){
            return res.render('login', { 'error': 'Invalid username or password.' }) 
          }
    
        if (username === userData.username && await passwordUtils.compare(password, userData.password)) {
    
          // 登入成功
          req.session.userId = userData.id
          req.session.user = userData.username // 在會話中存儲用戶信息
    
          res.redirect('/') // 登入成功後重定向到主頁或其他頁面
        }
    

以上對於如何將密碼加密的部分,

希望對大家有幫助~!

再來我們就會針對書單列表的增減進行小專案的製作,

大家明天見!


上一篇
Day 20 - 身分驗證與授權:實作使用者註冊和登入系統(中)
下一篇
Day 22 - RESTful API 設計:建立強大的 API 端點
系列文
30 天架設 Node.js - Express 框架:快速學習之路30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言