feng xiaohan

Bcrypt

一个跨平台的加密工具。

在 Node 上使用

下载

npm install --save bcryptjs

加密数据

使用bcrypt.hash()加密数据,该方法接收两个参数:

  • 第一个参数:需要加密的数据

  • 第二个参数:表示 hash 加密的轮数

    安全度越高,花费的时间就越长。12被认为是较高安全度的。

返回一个 Promise,内部传递一个加密后的数据:

const bcrypt = require("bcryptjs"); // 引入bcryptjs

const password = "sdfdsfdsafdsf";

// 注册
exports.postSignup = (req, res, next) => {
  const email = req.body.email;
  const password = req.body.password;
  const confirmPassword = req.body.confirmPassword;
  User.findOne({ email: email })
    .then((userDoc) => {
      if (userDoc) {
        return res.redirect("/signup");
      }
      return bcrypt
        .hash(password, 12) // 使用hash加密密码
        .then((hashedPassword) => {
          // 加密后的数据
          const user = new User({
            email: email,
            password: hashedPassword, // 用加密后的密码替换原密码传给数据库
            cart: { items: [] },
          });
          return user.save();
        })
        .then((result) => {
          res.redirect("/login");
        });
    })
    .catch((err) => {
      console.log(err);
    });
};

对比数据

由于数据经过 bcrypt 通过某种算法加密后,我们无法得知原信息是否与需要验证的信息相匹配,所以要通过 bcrypt 内部的来对比。可以使用bcrypt.compare()来进行对比,该方法接收两个参数:

  • 第一个参数:未经加密的数据
  • 第二个参数:经过 hash 加密后的数据

返回一个 Promise,内部传递一个 boolean 表示是否匹配:

// 登录
exports.postLogin = (req, res, next) => {
  const email = req.body.email;
  const password = req.body.password;
  User.findOne({ email: email })
    .then((user) => {
      if (!user) {
        return res.redirect("/login");
      }
      bcrypt
        .compare(password, user.password) // 将浏览器(用户)输入的密码和数据库中存储的hash密码进行匹配
        .then((doMatch) => {
          // 是否匹配
          if (doMatch) {
            req.session.isLoggedIn = true;
            req.session.user = user;
            return req.session.save((err) => {
              console.log(err);
              res.redirect("/");
            });
          }
          res.redirect("/login");
        });
    })
    .catch((err) => console.log(err));
};