1.
npm i bcryptjs
主要方法如下
const password = 'Red12345!' const hashedPassword = await bcrypt.hash(password, 8)
hash方法中設置8次權衡了安全與速度
const isMatch = await bcrypt.compare('red12345!', hashedPassword) console.log(isMatch)
compare方法直接比較 plain text password 和 hashed password ,如果一致則返回true
2.
因爲要在 User model 中引入 pre 中間件,所以設置 userSchema object,調用 userSchema.pre 方法
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true,
},
email: {
type: String,
required: true,
trim: true,
lowercase: true,
},
password: {
type: String,
required: true,
},
});
userSchema.pre("save", async function(next) {
const user = this;
if (user.isModified("password")) {
user.password = await bcrypt.hash(user.password, 8);
}
next();
});
const User = mongoose.model("User", userSchema);
module.exports = User;
這樣在userRouter中,每次 user.save()方法之前,都會加密密碼
const express = require("express");
const User = require("../models/user");
const router = new express.Router();
router.post("/api/users", async (req, res) => {
const user = new User(req.body);
try {
const result = await user.save();
res.status(201).send(result);
} catch (error) {
res.status(400).send();
}
});
module.exports = router;
3.
在 user model 中定義 statics ,注意有時候會自動 填寫成 static, 導致方法定義失敗
userSchema.statics.findByCredentials = async (email, password) => {
const user = await User.findOne({ email });
if (!user) {
throw new Error("Unable to login");
}
const isMatch = await bcrypt.compare(password, user.password);
if (!isMatch) {
throw new Error("Unable to login");
}
return user;
};
定義 api/users/login 接口
router.post("/api/users/login", async (req, res) => {
try {
const user = await User.findByCredentials(
req.body.email,
req.body.password
);
res.send(user);
} catch (error) {
res.status(400).send();
}
});