Node.js 密碼加密與儲存驗證

Kunyu
Oct 25, 2021
Photo by Timo Volz on Unsplash

密碼驗證

常見的網頁資料輸入驗證會讓使用者輸入兩次密碼,比對兩次是否相同。

驗證的方法可以使用 Mongoose Schema 當中的驗證屬性(Validate Property)。

const mongoose = require('mongoose');
const validator = require('validator');
const userSchema = new mongoose.Schema({
password: {
type: String,
required: [true, 'Please provide a password'],
minlength: 8,
},
passwordConfirm: {
type: String,
required: [true, 'Please confirm your password'],
validate: {
// 參數1 : 驗證器的值可以使用一個自定義函式。
// 參數2 : 當驗證結果等於 false 的時候回傳 message。
validator: function (el) {
return el === this.password;
},
message: 'Passwords are not the same!',
},
},
});
const User = mongoose.model('User', userSchema);module.exports = User;

雜湊加密

👉 對密碼進行雜湊加密(hash encryption)

👉 使用 bcrypt 雜湊加密演算法

👉 使用非同步版本

✍️ bcrypt 能夠將一個字串做雜湊加密,其中有個參數叫 saltRounds 是在密碼學中的加鹽(salt),加鹽的意思是在要加密的字串中加特定的字符,打亂原始的字符串,使其生成的散列結果產生變化,其參數越高加鹽次數多越安全相對的加密時間就越長。 — 引述自 andy6804tw

✍️ 該加多少鹽? bcrypt.hash第二個參數數值越大加鹽越多則越安全,其運算與電腦CPU有關係,預設值為10,2021年的今天電腦效能普遍不錯因此可以設定12來提升安全性,如果是20年前可能要降8來維持電腦運作速度。 — 引述自 Jonas Schmedtmann

userSchema.pre('save', async function (next) {
// guard clause(看守子句) : 如果密碼沒有變更,就直接傳到下一個中介軟體。
if (!this.isModified('password')) return next();
// 密碼進行雜湊處理 (cost 12)
this.password = await bcrypt.hash(this.password, 12);
// 刪除 passwordConfirm 欄位,因為只是拿來驗證,不需要儲存到資料庫。
this.passwordConfirm = undefined;
next();
});

事實上加密(Encrypt)與雜湊(Hash)並非指相同的事情,但具體內容已超出本文,建議延伸閱讀更為正確的相關資訊,一次搞懂密碼學中的三兄弟 — Encode、Encrypt 跟 Hash

--

--