Bcrypt是一种哈希加密算法,被广泛应用于存储密码和进行身份验证。并且Bcrypt算法包含一个重要特性即每次生成的哈希值都不同,这是由于Bcrypt算法在计算时会先生成一个随机的盐值与用户密码一起参与计算最终得到一个加密后的字符串。由于生成的盐值是随机的,所以即使每次使用相同的密码得到结果也是不同的。这样可以有效的防止攻击者使用一些手段破解用户密码。
/**
* 加密算法工具类
*/
public class BCryptUtils {
/**
* 生成加密后密文
*
* @param password 密码
* @return 加密字符串
*/
public static String encryptPassword(String password) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.encode(password);// 加密
}
/**
* 判断密码是否相同
*
* @param rawPassword 真实密码
* @param encodedPassword 加密后密文
* @return 结果
*/
public static boolean matchesPassword(String rawPassword, String encodedPassword) {
BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
return passwordEncoder.matches(rawPassword, encodedPassword);// 密码匹配
}
public static void main(String[] args) {
System.out.println(encryptPassword("123"));
System.out.println(matchesPassword("123", "$2a$10$Nm0bAesQKuPt5CWijLVbmOb5FXxRuoFUbHNwupVp.8DqbYQjf8iUW"));
}
package com.qyy.common.core.domain;
import com.qyy.common.core.enums.ResultCode;
import lombok.Getter;
import lombok.Setter;
//接口文档
@Getter
@Setter
public class R<T> {
private int code; //定义一些固定的code,前后端商量好的 0 1 请求成功 常量 2 3 枚举
private String msg; //? 通常是code的辅助说明 一个code 对应一个msg
private T data; //请求某个接口返回的数据list SysUser 泛型
//将封装result的封装方法可以写到R里面
// loginResult.setCode(ResultCode.FAILED_USER_NOT_EXISTS.getCode());
// loginResult.setMsg(ResultCode.FAILED_USER_NOT_EXISTS.getMsg());
// return loginResult;
public static <T> R<T> ok() {
return assembleResult(null, ResultCode.SUCCESS);
}
public static <T> R<T> ok(T data) {
return assembleResult(data, ResultCode.SUCCESS);
}
public static <T> R<T> fail() {
return assembleResult(null, ResultCode.FAILED);
}
public static <T> R<T> fail(int code, String msg) {
return assembleResult(code, msg, null);
}
/**
* 指定错误码
*
* @param resultCode 指定错误码
* @param <T>
* @return
*/
public static <T> R<T> fail(ResultCode resultCode) {
return assembleResult(null, resultCode);
}
private static <T> R<T> assembleResult(T data, ResultCode resultCode) {
R<T> r = new R<>();
r.setCode(resultCode.getCode());
r.setData(data);
r.setMsg(resultCode.getMsg());
return r;
}
private static <T> R<T> assembleResult(int code, String msg, T data) {
R<T> r = new R<>();
r.setCode(code);
r.setData(data);
r.setMsg(msg);
return r;
}
}
在SysUserServiceImpl类中 修改login方法,借助BCryptUtils.matchesPassword()方法,来判断 用户输入密码是否正确
@Override
//维护性、性能、安全
public R<String> login(String userAccount, String password) {
//通过账号去数据库中查询,对应的用户信息
LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
//select password from tb_sys_user where user_account = #{userAccount}
SysUser sysUser = sysUserMapper.selectOne(queryWrapper
.select(SysUser::getUserId, SysUser::getPassword, SysUser::getNickName)
.eq(SysUser::getUserAccount, userAccount));
return R.fail(ResultCode.FAILED_USER_NOT_EXISTS);
}
if (BCryptUtils.matchesPassword(password, sysUser.getPassword())) {
return R.ok();
}
return R.fail(ResultCode.FAILED_LOGIN);
}
测试成功