基于Redis如何实现每日登录失败次数限制的方法

67次阅读
没有评论

共计 2866 个字符,预计需要花费 8 分钟才能阅读完成。

自动写代码机器人,免费开通

这篇文章主要介绍基于 Redis 如何实现每日登录失败次数限制的方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

1. 思路

下面是我以前写的代码,没考虑高并发场景。如果是高并发场景下,要考虑到 redis 的 set 方法覆盖值问题,可以使用 incr 来替代 get,set 保证数据安全

通过 redis 记录登录失败的次数, 以用户的 username 为 key

每次收到登录的请求时, 都去 redis 查询登录次数是否已经大于等于我们设置的限制次数, 是的话直接返回

2. 代码

前台登录和后台查询数据库的代码省略

2.1 controller

我这里使用的 Jboot, 获取 redisTemplate 的方式是 Jboot.me().getRedis(), spring 的话用 jedisTemplate 就行.

//  如果用户输入账号密码有效登录超过限制次数,24 小时禁止登录
 //  设置一天限制失败次数, 默认为 10 次
 final int limit = 3;
 JbootRedis jr = Jboot.me().getRedis();
 //Constants.LOGIN_COUNT =  LOGIN_COUNT 
 //account 是页面传过来的 username
 String key = Constants.LOGIN_COUNT +  _  + account;
 Integer count = jr.get(key);
 if(count == null){
 count = 0;
 }else { if (count  = limit) {
 // 直接返回
 ajaxJson.setMsg( 您今天登录失败的次数已经超过限制,请明天再试。 ajaxJson.setSuccess(false);
 logger.error( 账号为【+account+】的用户单日登录次数超过上限 
 render(callback, gson.toJson(ajaxJson));
 return;
 }
 }
//...  去数据库根据 username 查询 user 对象
 if (user != null) {
 //  往 redis 中增加登录失败的次数
 Integer newCount = IncrFailLoginCount(key,count);
 logger.error(账号为【+account+】的用户登录失败, +ajaxJson.getMsg());
 ajaxJson.setMsg(ajaxJson.getMsg() + ,剩下登录次数为:+(limit-newCount));
 render(callback, gson.toJson(ajaxJson));
 return;
 }else{
 //  登录成功, 清除 redis 失败记录
 jr.del(key);
 }

2.2 IncrFailLoginCount 方法

/**
 *  一天中登录失败的次数统计
 * @param key redis 中存储的键
 * @param count  已经登录失败的次数
 * @return count  登录失败次数
 */
private Integer IncrFailLoginCount(String key,Integer count) { JbootRedis jr = Jboot.me().getRedis();
 count++;
 // 设置过期时间为今晚 23 点 59 分 59 秒
 long timeInMillis = DateUtils.getMillsecBeforeMoment(23, 59, 59, 999);
 if (timeInMillis   100){
 //  避免在最后一秒的时候登录导致过期时间过小甚至为负数
 timeInMillis = 1000*60;
 }
 //  设置过期时间
 jr.set(key,count);
 // 这里注意顺序,  先 set 再 pexpire
 jr.pexpire(key,timeInMillis);
 return count;
}

这里用到了时间的一个工具类, 具体代码如下:

/**
*  获取当前时间到指定时刻前的毫秒数
* @param hour  指定时刻的小时
* @param min  指定时刻的分钟
* @param sec  指定时刻的秒
* @param mill  指定时刻的毫秒
* @return
public static long getMillsecBeforeMoment(int hour,int min,int sec,int mill){ return getMillisecBetweenDate(new Date(),getMoment(hour,min,sec,mill));
*  获取两个日期之间的毫秒数
 * @param before
 * @param after
 * @return
 */
public static long getMillisecBetweenDate(Date before, Date after){ long beforeTime = before.getTime();
 long afterTime = after.getTime();
 return afterTime - beforeTime;
*  获取当天的某一时刻 Date
 * @param hour 24 小时
 * @param min  分钟
 * @param sec  秒
 * @param mill  毫秒
 * @return
 */
public static Date getMoment(int hour,int min,int sec,int mill){ Calendar calendar = Calendar.getInstance();
 calendar.setTime(new Date());
 calendar.set(Calendar.HOUR_OF_DAY,hour);
 calendar.set(Calendar.MINUTE,min);
 calendar.set(Calendar.SECOND,sec);
 calendar.set(Calendar.MILLISECOND,mill);
 return calendar.getTime();}

这里有个地方要注意, 就是 redis 设置过期时间后, 重新 set 会清除过期效果, 重新变成永久状态, 所以需要每次都 pexpire()
redis 中还有一个方法:incr(), 每次调用这个方法, 都会让一个键的值 +1, 如果没有这个键, 会初始为 0 再 +1. 适合做计数器, 也能再这个案例中使用, 但是我这里只是希望登录失败的时候才计数 +1 , 登录之前直接判断 count, 所以使用了传统的 get(),set(). 

以上是“基于 Redis 如何实现每日登录失败次数限制的方法”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注丸趣 TV 行业资讯频道!

向 AI 问一下细节

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-04发表,共计2866字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)