AboutPostsGithub

在【我的钱去哪儿了】中的密文存储和jwt验证

在项目【我的钱去哪了】中,涉及两个加密部分。

1.密码的密文存储

2.token的服务端验证

分别来说明这两个部分

一、使用bcryptjs进行的密文存储

在数据库中我们需要密文存储用户密码,并能在用户登录的时候进行比对,此时我使用了bcryptjs,它会根据我们输入的number生成salt、再使用salt进行加密存储。并且可以比较加密前后的密码是否一致。

var bcrypt = require('bcryptjs');
//密码加密模块


 exports.hash = async function (Password){
    let salt = await bcrypt.genSaltSync(10);
    // console.log(Password, salt);
    let result = await bcrypt.hash(Password, salt);
    // console.log(result);

    return result
}


exports.isEqual = async function (oldPwd, newPwd){
    // console.log(await bcrypt.compare(oldPwd, newPwd));
    return await bcrypt.compare(oldPwd, newPwd)
}

二、使用jwt进行的token验证

关于token自身的加密(或许叫做签名更合适),是在payload里加入某个字段,并使用存储在服务器端的salt加密。加解密都在服务器端利用jwt进行,这里我选择用user的name作为payload字段,当解密出来之后就与数据库中的username做比较,成功则以这个user的状态去进行权限操作。

const jwt = require("jsonwebtoken");
const config = require("../config")
const secretKey = config.jwtSecretKey;

// 生成token
module.exports.generateToken = function (payload) { 
  const token =
    "Bearer " +
    jwt.sign(payload, secretKey, {
      expiresIn: '365day',
    });
  return token;
};
module.exports.decodedToken = function (token) {
    return jwt.verify(token, secretKey, function (err, decoded) {
        return decoded.username;
    });
    
  };
// 验证token
module.exports.verifyToken = function (req, res, next) {
  const token = req.headers.authorization.split(" ")[1];
  jwt.verify(token, secretKey, function (err, decoded) {
    if (err) {
      // console.log("verify error", err);
      return res.json({ code: "404", msg: "token无效" });
    }
    console.log("通过验证,欢迎你,", decoded.username);
    next();
  });
};

三、存在的问题

1.前端向后端传输的密码依然是明文,而非密文。(此处可以考虑使用非对称加密)

2.token生成的salt一旦被获取,或是碰撞,服务器相当于不设防。(可以考虑每一个用户使用不同的salt,验证不需要解密,而是通过散列函数)