之前被问到一个问题,关于登陆次数限制的问题。比如我每天限制用户只能进行三次错误登陆操作,如果超过三次,那么就锁定账户,一天后才能再次登陆。

这个其实也不是很难,不过逻辑还是需要好好验证一下,目前我大概实现成功了,因为测试的次数也有限,所以可能有纰漏,还请各位斧正,不吝赐教。

项目结构、

testflight 多少账号 testflight一个账号次数_spring


testflight 多少账号 testflight一个账号次数_User_02


这个项目后来改名了,所以可能名字和GitHub上的不一致,GitHub上项目名是LoginTimes。

还有就是本人能力有限,所以不太会写前端的代码,只能用这种比较low的方式实现不同错误的跳转了。

另外这是我第一天尝试用eclipse,所以可能项目结构也会有点问题,各位见谅。
GitHub项目地址

直接把关键内容贴出来,其他的都是简单的增删改查什么的,不说了。
主要内容还是Controller里面的逻辑代码,如下
CASController.java

package com.yubotao.CookieAndSession;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.yubotao.POJO.User;
import com.yubotao.service.UserService;

@Controller
public class CASController {
	
	private static final Log log = LogFactory.getLog(CASController.class);
	
	@Autowired
	UserService userService;
	
	 @RequestMapping(value = "/login",method = RequestMethod.GET)
	 public String getlog(Map<String,Object> map){
	        map.put("user",new User());
	        return "login";
	 }
	
	@RequestMapping(value = "/login",method = RequestMethod.POST)
	public String login(HttpServletRequest request,HttpServletResponse response,User u) throws ServletException,IOException{
		
		String username = u.getUsername();
		String password = u.getPassword();
		
		if(username == null || password == null){
			return "paramsNull";
		}
		
		User realUser = userService.getUserByUsername(username);
		Long loginTime = System.currentTimeMillis();
		Integer wrongTimes = null;
		Integer locked = null;
		
		if(realUser == null){
			return "objectNull";
		}
		
		if((loginTime - realUser.getLastlogin()) > 24*3600*1000){
			realUser.setWrongtimes(0);
	
			realUser.setLocked(0);
			userService.updateUser(realUser);
		}
			
		if(realUser.getLocked() == 0){
			if((loginTime - realUser.getLastlogin()) > 5*60*1000){
				realUser.setLastlogin(loginTime);
				if(password.equals(realUser.getPassword())){
					
					userService.updateUser(realUser);
					return "success";
				}else{
					wrongTimes = realUser.getWrongtimes() + 1;
					if(wrongTimes > 2){
						locked = 1;
						realUser.setLocked(locked);
					}
					realUser.setWrongtimes(wrongTimes);
					userService.updateUser(realUser);
					return "pwWrong";
				}
			}else
				return "in5m";
		}
		
		return "fail";
		
	}

}

大概讲一下我的实现逻辑吧:

首先登陆需要判断的是,上次登陆时间和这次登陆时间差距是否大于24小时;如果大于24时,则将用户解锁并且将错误次数置0;然后判断用户是否属于锁定状态,如果非锁定,再判断用户是否在5分钟内再次登陆;大于5分钟时,此时不论用户帐密输入正确与否,都需要更新他的最近一次登陆时间;然后判断用户帐密是否正确,如果正确,更新用户到数据库,并返回成功;如果错误,对于用户的错误次数+1,并且判断错误次数是否已经是3次了,如果是3次就锁定用户;之后还是要更新用户到数据库,然后返回帐密错误信息。

整个流程大体如上,目前来看,逻辑貌似没有漏洞,如果有什么我没有考虑到的,还请不吝赐教,谢谢。