问题描述
- 前段页面输入的密码和存储在数据库中的加密的密码作比较,进行验证,验证通过,就进入用户页面,验证未通过,就进入登录界面
- 原问题代码
public BaseReturnInfo androidLogin(@RequestParam String phoneNumber, @RequestParam String pwd) {
BaseReturnInfo baseReturnInfo = new BaseReturnInfo();
UserInfo userInfo = userInfoRepository.getUserByPhoneNumber(phoneNumber);
if (userInfo == null) {
baseReturnInfo.setMsg("用户名或密码不正确");
baseReturnInfo.setStatus(1);
return baseReturnInfo;
}
if (pwd != userInfo.getPwd()) {
baseReturnInfo.setMsg("用户名或密码不正确");
baseReturnInfo.setStatus(1);
return baseReturnInfo;
}
baseReturnInfo.setMsg(userInfo.getCompanyName());
baseReturnInfo.setStatus(0);
return baseReturnInfo;
}
解决办法
public BaseReturnInfo androidLogin(@RequestParam String phoneNumber, @RequestParam String pwd) {
BaseReturnInfo baseReturnInfo = new BaseReturnInfo();
UserInfo userInfo = userInfoRepository.getUserByPhoneNumber(phoneNumber);
if (userInfo == null) {
baseReturnInfo.setMsg("用户名或密码不正确");
baseReturnInfo.setStatus(1);
return baseReturnInfo;
}
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();//重点
//页面传递过来的密码pwd 数据库中加密的密码 userInfo.getPwd()
boolean glag = bCryptPasswordEncoder.matches(pwd, userInfo.getPwd());//重点
if(!glag) {
baseReturnInfo.setMsg("用户名或密码不正确");
baseReturnInfo.setStatus(1);
return baseReturnInfo;
}
baseReturnInfo.setMsg(userInfo.getCompanyName());
baseReturnInfo.setStatus(0);
return baseReturnInfo;
}
原理
BCryptPasswordEncoder 的matches 方法
public boolean matches(CharSequence rawPassword, String encodedPassword) {
if (encodedPassword == null || encodedPassword.length() == 0) {
logger.warn("Empty encoded password");
return false;
}
if (!BCRYPT_PATTERN.matcher(encodedPassword).matches()) {
logger.warn("Encoded password does not look like BCrypt");
return false;
}
return BCrypt.checkpw(rawPassword.toString(), encodedPassword);
}
然后依靠源码来解决问题。
public class BCryptPasswordEncoder implements PasswordEncoder {
private Pattern BCRYPT_PATTERN = Pattern.compile("\\A\\$2a?\\$\\d\\d\\$[./0-9A-Za-z]{53}");
····
}
// 规则
String regex = "\\b\\w{3}\\b";
// 把规则编译成模式对象
Pattern p = Pattern.compile(regex);
// 通过模式对象得到匹配器对象
Matcher m = p.matcher(s);
// 调用匹配器对象的功能
// 通过find方法就是查找有没有满足条件的子串
// public boolean find()
public class BCrypt {}
public static boolean checkpw(String plaintext, String hashed) {
return equalsNoEarlyReturn(hashed, hashpw(plaintext, hashed));
}
参考文献
- https://blog.csdn.net/qq_35257397/article/details/52097647?fps=1&locationNum=6
- https://www.cnblogs.com/liwendeboke/p/6054690.html
- https://zhidao.baidu.com/question/276330953.html
- https://blog.csdn.net/Adonis_D_Gogh/article/details/79975526
备注
- 还是不要研究原理,否则越陷越深
- 按照上述写法,就可以实现前段页面输入的密码和后台数据库中的密码对比,就可以进入用户页面。
- 有点抄袭的成分,见谅