业务功能开发-登录(二)
验证(登录验证)
用户登录时根据登录账号信息获取到用户,然后根据登录密码,密码盐,密文调用PBKDF 2的验证方法进行验证处理,根据返回结果确认密码是否正确。
demo:LoginService.java( 验证账号是否存在,验证邮箱是否存在,验证身份证是否存在,验证手机号是否存在,验证UserInfo表中的某一列是否唯一可用, 用户登录后台验证)
在登录验证的第三步,有对密码错误次数超限的验证,当密码错误达到指定次数就锁定账号,锁定时间单位为小时。在init.properties文件中有密码错误最大次数和锁定最新时间的配置,默认最大错误次数是6,锁定时间是6小时
public int login(HttpServletRequest request, HttpServletResponse response, String userName, String passWord, boolean autoLogin) {
// 1.取用户
User user = null;
Object userObj = User.dao.cacheGet(userName);
if (null != userObj) {
user = (User) userObj;
} else {
Map<String, Object> param = new HashMap<String, Object>();
param.put("column", User.column_username);
String sql = getSqlByBeetl(User.sqlId_column, param);
List<User> userList = User.dao.find(sql, userName);
if (userList.size() != 1) {
return ConstantLogin.login_info_0;// 用户不存在
}
user = userList.get(0);
}
// 2.停用账户
String status = user.getStr(User.column_status);
if (status.equals("0")) {
return ConstantLogin.login_info_1;
}
// 3.密码错误次数超限
long errorCount = user.getNumber(User.column_errorcount).longValue();
int passErrorCount = PropKit.getInt(ConstantInit.config_passErrorCount_key);
if(errorCount >= passErrorCount){
Date stopDate = user.getDate(User.column_stopdate);
int hourSpace = ToolDateTime.getDateHourSpace(ToolDateTime.getDate(), stopDate);
int passErrorHour = PropKit.getInt(ConstantInit.config_passErrorHour_key);
if(hourSpace < passErrorHour){
return ConstantLogin.login_info_2;// 密码错误次数超限,几小时内不能登录
}else{
String sql = getSql(User.sqlId_start);
Db.use(ConstantInit.db_dataSource_main).update(sql, user.getPKValue());
// 更新缓存
User.dao.cacheAdd(user.getPKValue());
}
}
// 4.验证密码
byte[] salt = user.getBytes(User.column_salt);// 密码盐
byte[] encryptedPassword = user.getBytes(User.column_password);
boolean bool = false;
try {
bool = ToolPbkdf2.authenticate(passWord, encryptedPassword, salt);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
if (bool) {
// 密码验证成功
AuthInterceptor.setCurrentUser(request, response, user, autoLogin);// 设置登录账户
return ConstantLogin.login_info_3;
} else {
// 密码验证失败
String sql = getSql(User.sqlId_stop);
Db.use(ConstantInit.db_dataSource_main).update(sql, ToolDateTime.getSqlTimestamp(ToolDateTime.getDate()), errorCount+1, user.getPKValue());
// 更新缓存
User.dao.cacheAdd(user.getPKValue());
return ConstantLogin.login_info_4;
}
}
//用户登录时,根据存储的密码盐和密文来验证登录密码的正确性,登陆成功后会根据登录的多种信息使用IDEA加密成密文写入cookie,并根据是否自动登录设定cookie的有效时间
//在以后每次接受请求时都根据cookie的加密登录信息解密来验证用户的有效性。