【java登录锁定功能】redis实现登录失败锁定账号

登录失败(账号密码<5次时不提示),>=5次时,锁定时间5min,最高密码错误次数为10,第十次密码输入错误后,提醒,“账号已停用,请联系管理员开通”,次日0时,重新计算错误次数

代码实现



    public static String LOGIN_FAIL_LOCK = "login:error:count:";
    public static String LOGIN_FAIL_COUNT = "lock";

    @GetMapping("login")
    public void login(String userName, String password) {
        RedisUtil redisUtil = new RedisUtil();
        TyqUser tyqUser = this.selectUserFromMysql(userName);
        // 判断当前账号是否被锁定
        String errorMessage = this.judgeLock(userName);
        if (StrUtil.isNotEmpty(errorMessage)) {
            throw new BizException(errorMessage);
        }
        String loginFailLockKey = LOGIN_FAIL_LOCK + userName;
        String loginFailCountKey = LOGIN_FAIL_COUNT + userName;
        String msg = null;
        if (!tyqUser.getPassword().equals(userName)) {
            // 密码错误,进行封禁账号
            msg = loginFailLockJudge(loginFailLockKey, loginFailCountKey, tyqUser.getId());
        } else {
            // 登录成功,清空对应的 锁定次数
            redisUtil.delete(loginFailCountKey);
            redisUtil.delete(loginFailLockKey);
        }
    }



    // 模拟从数据库查询user
    public TyqUser selectUserFromMysql(String userName){
        return new TyqUser();
    }

    // 判断当前账号是否可以进行登录
    public String judgeLock(String userName) {
        RedisUtil redisUtil = new RedisUtil();
        BizResponse<Object> bizResponse = null;
        if (StrUtil.isEmpty(userName)) {
            return null;
        }
        Map<String, Object> param = new HashMap<>();
        TyqUser user = this.selectUserFromMysql(userName);
        // 查询 user 的状态,是否停用,禁用
        if ("停用".equals(user.getStatus())) {
            return "账号已停用";
        }
        // 判断账号是否锁定,锁定就进行提示
        String msg = null;
        String loginFailLockKey = LOGIN_FAIL_LOCK + userName;
        String loginFailCountKey = LOGIN_FAIL_COUNT + userName;
        if (redisUtil.getObject(loginFailCountKey) != null) {
            String loginFailCountValue = String.valueOf(redisUtil.getObject(loginFailCountKey));
            if (Integer.parseInt(loginFailCountValue) > 4) {
                if (redisUtil.getObject(loginFailLockKey) != null) {
                    Long ttlForLoginFailLock = redisUtil.ttl(loginFailLockKey);
                    if (ttlForLoginFailLock > 0) {
                        String minuteLeft = TimeUtil.getMinuteStringFromSeconds(ttlForLoginFailLock);
                        msg = "输入错误次数过多, 请" + minuteLeft + "后再试";
                        return msg;
                    }
                }
            }
        }
        return msg;
    }

    public int updateStatus(String id, String status) {
        return 1;
    }
    // 登录失败次数校验
    public String loginFailLockJudge(String loginFailLockKey, String loginFailCountKey, String id) {
        RedisUtil redisUtil = new RedisUtil();
        // 当前时间到次日零点的剩余时间
        Long remainToZero = ChronoUnit.SECONDS.between(LocalDateTime.now(), LocalDateTime.now().plusDays(1).withHour(0).withMinute(0).withSecond(0));
        // key
        String loginFailCountValue = redisUtil.get(loginFailCountKey);
        String msg = null;
        Long maxTtl = 5 * 60L;
        if (StrUtil.isNotEmpty(loginFailCountValue)) {
            Integer loginFailCount = Integer.parseInt(loginFailCountValue);
            loginFailCount ++;
            // 前5次登录失败,提示错误信息
            if (loginFailCount < 5) {
                redisUtil.setObjectAndExpireSeconds(loginFailLockKey, loginFailCount, remainToZero);
                redisUtil.setObjectAndExpireSeconds(loginFailCountKey, loginFailCount, remainToZero);
                msg = "密码错误,请再次输入";
                return msg;
            }
            if (loginFailCount < 10) {
                Long ttl = maxTtl;
                if(ttl > remainToZero) {
                    ttl = remainToZero;
                }
                redisUtil.setObjectAndExpireSeconds(loginFailLockKey, loginFailCount, ttl);
                redisUtil.setObjectAndExpireSeconds(loginFailCountKey, loginFailCount, ttl);
                String minuteLeft = TimeUtil.getMinuteStringFromSeconds(ttl);
                msg = "密码错误次数频繁,请" + minuteLeft + "后再试";
            } else {
                // 修改mysql中的账号状态
                this.updateStatus(id, "停用");
                msg = "账号已停用";
            }
        } else {
            // 第一次登录失败
            redisUtil.setObjectAndExpireSeconds(loginFailLockKey, "1", remainToZero);
            redisUtil.setObjectAndExpireSeconds(loginFailCountKey, "1", remainToZero);
            msg = "密码错误,请再次输入";
        }
        return msg;
    }




您可以使用Java实现Redis中调取验证信息进行登录功能。下面是一个基本的示例代码: 首先,确保已经安装了JavaRedis,并且已经配置好了Redis的连接信息。 ```java import redis.clients.jedis.Jedis; public class RedisLogin { private static final String REDIS_HOST = "localhost"; // Redis服务器主机 private static final int REDIS_PORT = 6379; // Redis服务器端口 public static void main(String[] args) { // 创建Redis客户端 Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT); // 模拟用户登录 String username = "john"; String password = "password"; // 从Redis中获取存储的验证信息 String storedUsername = jedis.hget("users", "username"); String storedPassword = jedis.hget("users", "password"); // 验证用户登录 if (username.equals(storedUsername) && password.equals(storedPassword)) { System.out.println("登录成功!"); } else { System.out.println("用户名或密码错误!"); } // 关闭Redis客户端连接 jedis.close(); } } ``` 在上面的示例中,我们使用Jedis库来连接Redis服务器。首先,创建一个Jedis对象并指定Redis服务器的主机和端口。然后,模拟用户登录时提供的用户名和密码。接下来,使用`hget`方法从Redis中获取存储的用户名和密码。最后,通过比较输入的用户名和密码与存储的用户名和密码来验证用户登录。 请注意,上述代码仅为示例,您可以根据实际需求进行修改和扩展。另外,为了安全起见,建议将密码加密存储,并使用其他安全机制来保护用户登录。 希望对您有帮助!如有更多问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值