纯java代码实现登录次数验证,登录错误5次以后锁定30分钟

本方法由于是根据思路纯手写,代码能够再简化,功能尝试没问题,最主要就是在登录验证中的逻辑,checkLogin()方法是登陆前的验证,而真正的登录方式采用的是Shiro,若不是采用Shiro登录,将该逻辑采用到本身登录的方法中便可实现java

1、用户验证必须字段  用户实体类中User.java添加一下字段,可自选持久化工具,本次采用jpa做为持久化工具数据库

除了用户id,帐户,密码以外其中还必须有三个字段lastLoginErrorTime最后一次登录错误时间、loginErrorcount登录错误计数、isLocked是否锁定(0、未锁定;一、锁定)session

@Entity
@Table(name = "user_info")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class UserInfo implements Serializable{
	private static final long serialVersionUID = 1L;
	/**
	 * 用户模式(0,为管理员;1,为普通用户)
	 */
	@Column
	private Integer userModel=1;//默认为普通用户
	
//	public static enum UserType {
//		SUPER, NORMAL
//	}
	/**
	 * 主键
	 */
	@Id
	@Column(name = "user_id")
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Integer userId;
	/**
	 * 登陆账号
	 */
	@Column//(unique = true)
	private String userName;
	/**
	 * 用户密码
	 */
	@Column
	private String password="";
	/**
	 * 角色对应外键
	 */
	@Column
	private Integer roleId;
	/**
	 * 部门对应外键
	 */
	@Column
	private Integer departmentId;
	/**
	 * 添加时间
	 */
	@Column
	private Date addTime;
	/**
	 * 最后一次登陆时间
	 */
	@Column
	private Date lastLoginTime;
	
	/**
	 * 最后一次登录错误时间
	 */
	@Column(name = "last_login_error_time",columnDefinition="DATETIME COMMENT '最后一次登录错误时间'")
	private Date lastLoginErrorTime;
	/**
	 * 登录错误计数
	 */
	@Column(name = "login_rrror_count",columnDefinition="DATETIME COMMENT '登录错误计数'")
	private Integer loginErrorcount;
	/**
	 * 是否锁定(0、未锁定;一、锁定)
	 */
	@Column(name = "is_locked",columnDefinition="DATETIME COMMENT '是否锁定'")
	private Integer isLocked;


    // get/set方法此处省略
}

2、对应数据库工具

3、登录方法中进行判断验证out.print()打印的是前台接收的Json字符串this

/**
	 * 检查登陆是否正确并判断登陆项目
	 * 
	 * @throws IOException
	 */
	public void checkLogin() throws IOException {
		StatusPrinter.print(lc);
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setCharacterEncoding(DEFAULT_CHARACTER_UTF8);
		PrintWriter out = response.getWriter();
		HttpSession session = ServletActionContext.getRequest().getSession();
		// 获得系统保存的验证码
		String valiCode = (String) session.getAttribute("rand");
		if (valiCode == null) {
			out.print("{\"result\":\"验证码失效,请刷新页面后重试。\",\"msg\":\"系统错误,刷新后重试。\"}"); // 刷新登陆
			out.flush();
			out.close();
			return; // 返回结束;
		}
		// 若是验证码错误
		if (!valiCode.equals(rand)) {
			out.print(ActionResult.ErrMsg("验证码错误。")); // 刷新登陆
			out.flush();
			out.close();
			return; // 返回结束;
		}
		UserInfo user = userService.getUserByUserName(username);
		Date thisErrorLoginTime = null;		// 修改的本次登录错误时间
		Integer islocked = 0;			// 获取是否锁定状态
		if (user == null) {				// 帐号密码有问题
			out.print(ActionResult.ErrMsg("不存在此用户"));
		} else if (user.getStatus()==1) {
			out.print(ActionResult.ErrMsg("此用户已被删除"));
		} else if (!user.getPassword().equals(MD5.getMD5(password.getBytes()))) {
			if (user.getIsLocked() == null) {
				user.setIsLocked(0);
			} else {
				islocked = user.getIsLocked();
			}
			if (user.getLoginErrorcount() == null) {
				user.setLoginErrorcount(0);
			}
			Date date = new Date();
			SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			String datestr = format.format(date);
			try {
				thisErrorLoginTime = format.parse(datestr);
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (islocked == 1) {							// 帐户被锁定 // 被锁定是登录错误次数必定是5,因此只判断一次
				Date lastLoginErrorTime = null; // 最后一次登录错误时间
				Long timeSlot = 0L;
				if (user.getLastLoginErrorTime() == null) {
					lastLoginErrorTime = thisErrorLoginTime;
				} else {
					lastLoginErrorTime = user.getLastLoginErrorTime();
					timeSlot = thisErrorLoginTime.getTime() - lastLoginErrorTime.getTime();
				} 
				if (timeSlot < 1800000) {	// 判断最后锁定时间,30分钟以内继续锁定
					out.print(ActionResult.ErrMsg("您的帐户已被锁定,请" + (30-Math.ceil((double)timeSlot/60000)) + "分钟以后再次尝试"));
				} else {									// 判断最后锁定时间,30分钟以后还是错误,继续锁定30分钟
					user.setLastLoginErrorTime(thisErrorLoginTime);
					userService.addUser(user);
					out.print(ActionResult.ErrMsg("帐户或密码错误,您的帐户已被锁定,请30分钟以后再次尝试登录"));
				}	
			} else if (user.getLoginErrorcount() == 4) {	// 帐户第五次登录失败  ,此时登录错误次数增长至5,之后错误还是5,再也不递增
				user.setLoginErrorcount(5);
				user.setIsLocked(1);
				user.setLastLoginErrorTime(thisErrorLoginTime);
				userService.addUser(user);					//修改用户
				out.print(ActionResult.ErrMsg("您的帐户已被锁定,请30分钟以后再次尝试登录"));
			} else {										// 帐户前四次登录失败
				user.setLoginErrorcount(user.getLoginErrorcount() + 1);
				user.setLastLoginErrorTime(thisErrorLoginTime);
				userService.addUser(user);					//修改用户
				out.print(ActionResult.ErrMsg("帐户或密码错误,您还有" + (5-user.getLoginErrorcount()) +"次登录机会"));
			}
		} else {
			islocked = user.getIsLocked();
			if (islocked == 1) {
				Date lastLoginErrorTime = null; // 最后一次登录错误时间
				Long timeSlot = 0L;
				if (user.getLastLoginErrorTime() == null) {
					lastLoginErrorTime = new Date();
				} else {
					lastLoginErrorTime = user.getLastLoginErrorTime();
					timeSlot = new Date().getTime() - lastLoginErrorTime.getTime();
				} 
				if (timeSlot < 1800000) {	// 判断最后锁定时间,30分钟以内继续锁定
					out.print(ActionResult.ErrMsg("您的帐户已被锁定,请" + (30-Math.ceil((double)timeSlot/60000)) + "分钟以后再次尝试"));
				} else {									// 判断最后锁定时间,30分钟以后登录帐户
					RoleInfo r=roleService.getRoleById(user.getRoleId());
					if(r.getStatus()==1){
						out.print("{\"result\":\"该用户拥有的角色已被管理员删除,请于管理员联系。\"}");
					}else{
						session.setAttribute("user", user);// 保存当前用户
						Date d=new Date();
			            session.setAttribute("dateStr", d); // 保存当前用户登陆时间用于显示  
						user.setLoginErrorcount(0);
						user.setIsLocked(0);
			            user.setLastLoginTime(user.getLoginTime());
			            user.setLastLoginIp(user.getLoginIp());
			            user.setLoginTime(d);
			            user.setLoginIp(ServletActionContext.getRequest().getRemoteAddr());
			            userService.addUser(user);//修改用户表登陆时间
			//            logService.addOperationLog("登陆系统");
			            log.info("登陆系统");
						out.print(ActionResult.SUCCESS);
					}
				}	
			} else {
				RoleInfo r=roleService.getRoleById(user.getRoleId());
				if(r.getStatus()==1){
					out.print("{\"result\":\"该用户拥有的角色已被管理员删除,请于管理员联系。\"}");
				}else{
					session.setAttribute("user", user);// 保存当前用户
					Date d=new Date();
		            session.setAttribute("dateStr", d); // 保存当前用户登陆时间用于显示  
					user.setLoginErrorcount(0);
					user.setIsLocked(0);
		            user.setLastLoginTime(user.getLoginTime());
		            user.setLastLoginIp(user.getLoginIp());
		            user.setLoginTime(d);
		            user.setLoginIp(ServletActionContext.getRequest().getRemoteAddr());
		            userService.addUser(user);//修改用户表登陆时间
		//            logService.addOperationLog("登陆系统");
		            log.info("登陆系统");
					out.print(ActionResult.SUCCESS);
				}
			}
		}
		out.flush();
		out.close();
	}

4、实现的逻辑code