我们要实现的就是,密码连续输入错误5次,就限制用户十分钟不能进行登录。
大致的流程图

数据库设计如下
代码语言:javascript复制DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(64) NOT NULL COMMENT '用户名',
`password` varchar(255) NOT NULL COMMENT '用户密码',
`email` varchar(64) DEFAULT NULL COMMENT '用户邮箱',
`status` int(11) NOT NULL DEFAULT '0'
COMMENT '状态,1代表删除',
`admin` int(11) NOT NULL DEFAULT '0'
COMMENT '是否是管理员,1代表是管理员',
`iphone` varchar(20) DEFAULT NULL
COMMENT '用户手机号',
`workid` int(11) NOT NULL DEFAULT '0',
`token` varchar(255) DEFAULT NULL,
`errornum` int(2) NOT NULL DEFAULT '0',
`freeze` int(2) NOT NULL DEFAULT '0',
`freezetime` datetime DEFAULT NULL,
PRIMARY KEY (`id`,`username`),
KEY `username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=49
DEFAULT CHARSET=utf8 COMMENT='用户表';那么我们来实现dao层
代码语言:javascript复制package pan.DaoObject;
import
com.fasterxml.jackson.annotation.
JsonIgnoreProperties;
import lombok.Data;
import org.hibernate.annotations.DynamicUpdate;
import pan.enmus.FreezeEmus;
import pan.enmus.UserEmus;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;
import java.util.Date;@Data
@DynamicUpdate
@Entity
@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler"})public class User implements Serializable {
@Id
@GeneratedValue(strategy =
GenerationType.IDENTITY)
private Integer id;
private String username;
private String password;
private String email;
private String iphone;
private Integer status =
UserEmus.UNDELETE.getCode();
private Integer admin = UserEmus.NOTADMIN.getCode();
private String token;
private Date freezetime;
private Integer errornum;
private Integer freeze= FreezeEmus.
UNDELETE.getCode();
}对应的UserEmus
代码语言:javascript复制package pan.enmus;import lombok.Getter;@Getterpublic enum UserEmus {
ADMIN(1, "管理员"),
NOTADMIN(0, "非管理员"),
DELETE(1, "删除"),
UNDELETE(0, "正常");
private Integer code;
private String message;
UserEmus(Integer code, String message) {
this.code = code;
this.message = message;
}
}代码语言:javascript复制FreezeEmus 为:代码语言:javascript复制package pan.enmus;import lombok.Getter;@Getterpublic enum FreezeEmus {
DELETE(1,"冻结"),
UNDELETE(0,"正常");
private Integer code;
private String message;
FreezeEmus(Integer code, String message){
this.code=code;
this.message=message;
}
}那么接下来,我们就是UserRepository实现
代码语言:javascript复制public interface UserRepository extends JpaRepository<User, Integer> {代码语言:javascript复制User findByUsername(String username);代码语言:javascript复制}里面就用到了一个通过username查找用户
那么我们接下来去实现service
代码语言:javascript复制@Servicepublic class UserSericeImpl {
@Autowired
private UserRepository userRepository;代码语言:javascript复制@Override
public User login(String username, String password) {
User user = userRepository.
findByUsername(username);
if (user != null) {
if (user.getStatus().equals
( UserEmus.DELETE.getCode())){
throw new PanExection
(ResultEmus.USER_DELETE);
}
SimpleDateFormat format=
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
try {
if(user.getFreeze().equals(
FreezeEmus.DELETE.getCode())&&
(new Date().getTime()-format.parse
(user.getFreezetime().toString()).
getTime()<6*60*1000)){
user.setErrornum(0);
userRepository.saveAndFlush(user);
throw new PanExection(ResultEmus.
USER_FREE);
}
} catch (ParseException e) {
e.printStackTrace();
}
}catch (NullPointerException e){
userRepository.saveAndFlush(user);
}
Boolean b = null;
try {
b = MD5Until.
checkoutpassword(password,
user.getPassword());
} catch (Exception e) {
throw new
PanExection(ResultEmus.EXCEPTIONS);
}
if (b) {
String key = "Plan_"
user.getUsername();
String tokned = (String)
userredis(redisTemplate)
.opsForValue()
.get(key);
user.setErrornum(0);
user.setFreezetime(null);
if (tokned == null) {
Date date = new Date();
String tokne = null;
try {
tokne = MD5Until.md5
(key date.toString());
} catch (Exception e) {
throw new
PanExection
(ResultEmus.EXCEPTIONS);
}
String token = user.getUsername() "_" tokne;
user.setToken(token);
userRepository.saveAndFlush(user);
userredis(redisTemplate)
.opsForValue().set
(key, token, 1, TimeUnit.DAYS);
return user;
} else {
userRepository.saveAndFlush(user);
return user;
}
}else {
if(user.getErrornum()>4){
user.setErrornum(user.getErrornum() 1);
user.setFreeze(FreezeEmus.DELETE.getCode());
user.setFreezetime(new Date());
userRepository.saveAndFlush(user);
throw new PanExection(ResultEmus.USER_FREE);
}else {
Integer err=user.getErrornum() 1;
user.setErrornum(err);
userRepository.saveAndFlush(user);
throw new PanExection(ResultEmus.USER_ERROR_PASSWORD);
}
}
}
throw new PanExection(ResultEmus.USER_NOT_EXIT);
}代码语言:javascript复制}代码语言:javascript复制我们最后去实现一个contorller类代码语言:javascript复制import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.
Autowired;
import org.springframework.data.redis.core.
RedisTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import pan.DaoObject.User;
import pan.Form.UserForm;
import pan.config.RedisConfig;
import pan.converter.UserForm2User;
import pan.enmus.ResultEmus;
import pan.exection.PanExection;
import pan.service.FileService;
import pan.service.UserSerice;
import pan.untils.RedisDbInit;
import pan.untils.ResultVOUntils;
import pan.vo.ResultVO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.HashMap;import java.util.Map;@RestController
@Api(tags = "2.4", description = "登录",
value = "实现登录")
@RequestMapping("/plan")public class LoginContorl {
@Autowired private UserSerice userSerice;
@Autowired private RedisTemplate redisTemplate;
@Autowired private FileService fileService;
private RedisTemplate setusertoken
(RedisTemplate redisTemplate) {
redisTemplate =
RedisDbInit.initRedis(RedisConfig.userreidport,
redisTemplate);
return redisTemplate;
} @ApiOperation(value = "登录", notes = "用户登录") @PostMapping(value = "/login",
produces = "application/json")
public ResultVO login(@Valid UserForm userForm,
BindingResult bindingResult
) {
if (bindingResult.hasErrors()) {
throw new PanExection
(ResultEmus.PARM_ERROR.getCode(),
bindingResult.getFieldError().getDefaultMessage());
}
User user = UserForm2User.convert(userForm);
User login = userSerice.login
(user.getUsername(), user.getPassword());
Map<String, String> map = new HashMap<>();
String redis = (String)
setusertoken(redisTemplate).opsForValue().
get("Plan_" user.getUsername());
Boolean superadmin=userSerice.usersuperadmin
(login.getId());
if(superadmin){
map.put("is_super","1");
}else{
map.put("is_super","0");
} if (login != null) {
map.put("userid", login.getId().toString());
map.put("token", redis);
return ResultVOUntils.success(map);
}
return ResultVOUntils.error(1, "密码或者用户名错误");
}
}到此我们的代码部分已经实现,
补充
代码语言:javascript复制ResultVOUntils代码代码语言:javascript复制public class ResultVOUntils {
public static ResultVO success(Object object){
ResultVO resultVO=new ResultVO();
resultVO.setData(object);
resultVO.setMsg("成功");
resultVO.setCode(0);
return resultVO;
}
public static ResultVO success(){
return success(null);
}
public static ResultVO error
(Integer code ,String msg){
ResultVO resultVO=new ResultVO();
resultVO.setCode(code);
resultVO.setMsg(msg);
return resultVO;
}
public static ResultVO error(Object object){
ResultVO resultVO=new ResultVO();
resultVO.setData(object);
resultVO.setMsg("失败");
resultVO.setCode(1);
return resultVO;
}
}restultvo代码
代码语言:javascript复制import lombok.Data;@Datapublic class ResultVO<T> {
private Integer code;
private String msg;
private T data;
}代码语言:javascript复制PanExection代码代码语言:javascript复制package pan.exection;
import lombok.Getter;
import pan.enmus.CaseResultEmus;
import pan.enmus.ResultEmus;
@Getterpublic class PanExection extends
RuntimeException {
private Integer code;
public PanExection(ResultEmus resultEmuns) { super(resultEmuns.getMessage()); this.code = resultEmuns.getCode();
}
public PanExection(CaseResultEmus resultEmuns) { super(resultEmuns.getMessage()); this.code = resultEmuns.getCode();
}
public PanExection(Integer code, String message) { super(message); this.code = code;
}
}那么到现在我们的代码已经实现 完毕,那么我们去实验下,
使用数据 lileilei 密码lileilei 进行校验
使用postman进行测试,密码输入正确返回结果正常

密码输入错误超出后

补充ResultEmus代码:代码语言:javascript复制package pan.enmus;import lombok.Getter;@Getterpublic enum ResultEmus {
SUCCESS_REQUEST(0, "成功"),
USER_NOT_EXIT(1, "用户不存在"),
USER_BIND(2, "用户已经绑定"),
USER_DELETE(3, "用户已经删除"),
EXCEPTIONS(4, "转化异常"),
USER_ERROR_PASSWORD(225, "密码错误"),
USER_FREE(115,"你已经被冻结,密码输入次数超过五次,
请10分钟再来登录"),
;
private Integer code;
private String message; ResultEmus(Integer code, String message) { this.code = code; this.message = message;
}
}代码语言:javascript复制到这里,我们的登录已经实现完毕。在标准的工程里面可以正常实现,
由于我配置了阿里的druid的监控
那么我可以看到相应的监控信息sql执行情况这样我们用mysql实现的简单的用户名密码输入错误5次,限制登录十分钟就实现完毕。
代码语言:javascript复制其实我还是感觉这里面是有bug的,后续有空我会来测试下这里的代码。


