亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Redis > 正文

redis 實現登陸次數限制的思路詳解

2020-10-28 21:29:28
字體:
來源:轉載
供稿:網友

title: redis-login-limitation 

利用 redis 實現登陸次數限制, 注解 + aop, 核心代碼很簡單.

基本思路

比如希望達到的要求是這樣: 在 1min 內登陸異常次數達到5次, 鎖定該用戶 1h

那么登陸請求的參數中, 會有一個參數唯一標識一個 user, 比如 郵箱/手機號/userName

用這個參數作為key存入redis, 對應的value為登陸錯誤的次數, string 類型, 并設置過期時間為 1min. 當獲取到的 value == "4" , 說明當前請求為第 5 次登陸異常, 鎖定.

所謂的鎖定, 就是將對應的value設置為某個標識符, 比如"lock", 并設置過期時間為 1h

核心代碼

定義一個注解, 用來標識需要登陸次數校驗的方法

package io.github.xiaoyureed.redispractice.anno;import java.lang.annotation.*;@Documented@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface RedisLimit {  /**   * 標識參數名, 必須是請求參數中的一個   */  String identifier();  /**   * 在多長時間內監控, 如希望在 60s 內嘗試   * 次數限制為5次, 那么 watch=60; unit: s   */  long watch();  /**   * 鎖定時長, unit: s   */  long lock();  /**   * 錯誤的嘗試次數   */  int times();}

編寫切面, 在目標方法前后進行校驗, 處理...

package io.github.xiaoyureed.redispractice.aop;@Component@Aspect// Ensure that current advice is outer compared with ControllerAOP// so we can handling login limitation Exception in this aop advice.//@Order(9)@Slf4jpublic class RedisLimitAOP {  @Autowired  private StringRedisTemplate stringRedisTemplate;  @Around("@annotation(io.github.xiaoyureed.redispractice.anno.RedisLimit)")  public Object handleLimit(ProceedingJoinPoint joinPoint) {    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();    final Method   method     = methodSignature.getMethod();    final RedisLimit redisLimitAnno = method.getAnnotation(RedisLimit.class);// 貌似可以直接在方法參數中注入 todo    final String identifier = redisLimitAnno.identifier();    final long  watch   = redisLimitAnno.watch();    final int  times   = redisLimitAnno.times();    final long  lock    = redisLimitAnno.lock();    // final ServletRequestAttributes att       = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();    // final HttpServletRequest    request     = att.getRequest();    // final String          identifierValue = request.getParameter(identifier);    String identifierValue = null;    try {      final Object arg      = joinPoint.getArgs()[0];      final Field declaredField = arg.getClass().getDeclaredField(identifier);      declaredField.setAccessible(true);      identifierValue = (String) declaredField.get(arg);    } catch (NoSuchFieldException e) {      log.error(">>> invalid identifier [{}], cannot find this field in request params", identifier);    } catch (IllegalAccessException e) {      e.printStackTrace();    }    if (StringUtils.isBlank(identifierValue)) {      log.error(">>> the value of RedisLimit.identifier cannot be blank, invalid identifier: {}", identifier);    }    // check User locked    final ValueOperations<String, String> ssOps = stringRedisTemplate.opsForValue();    final String             flag = ssOps.get(identifierValue);    if (flag != null && "lock".contentEquals(flag)) {      final BaseResp result = new BaseResp();      result.setErrMsg("user locked");      result.setCode("1");      return new ResponseEntity<>(result, HttpStatus.OK);    }    ResponseEntity result;    try {      result = (ResponseEntity) joinPoint.proceed();    } catch (Throwable e) {      result = handleLoginException(e, identifierValue, watch, times, lock);    }    return result;  }  private ResponseEntity handleLoginException(Throwable e, String identifierValue, long watch, int times, long lock) {    final BaseResp result = new BaseResp();    result.setCode("1");    if (e instanceof LoginException) {      log.info(">>> handle login exception...");      final ValueOperations<String, String> ssOps = stringRedisTemplate.opsForValue();      Boolean                exist = stringRedisTemplate.hasKey(identifierValue);      // key doesn't exist, so it is the first login failure      if (exist == null || !exist) {        ssOps.set(identifierValue, "1", watch, TimeUnit.SECONDS);        result.setErrMsg(e.getMessage());        return new ResponseEntity<>(result, HttpStatus.OK);      }      String count = ssOps.get(identifierValue);      // has been reached the limitation      if (Integer.parseInt(count) + 1 == times) {        log.info(">>> [{}] has been reached the limitation and will be locked for {}s", identifierValue, lock);        ssOps.set(identifierValue, "lock", lock, TimeUnit.SECONDS);        result.setErrMsg("user locked");        return new ResponseEntity<>(result, HttpStatus.OK);      }      ssOps.increment(identifierValue);      result.setErrMsg(e.getMessage() + "; you have try " + ssOps.get(identifierValue) + "times.");    }    log.error(">>> RedisLimitAOP cannot handle {}", e.getClass().getName());    return new ResponseEntity<>(result, HttpStatus.OK);  }}

這樣使用:

package io.github.xiaoyureed.redispractice.web;@RestControllerpublic class SessionResources {  @Autowired  private SessionService sessionService;  /**   * 1 min 之內嘗試超過5次, 鎖定 user 1h   */  @RedisLimit(identifier = "name", watch = 30, times = 5, lock = 10)  @RequestMapping(value = "/session", method = RequestMethod.POST)  public ResponseEntity<LoginResp> login(@Validated @RequestBody LoginReq req) {    return new ResponseEntity<>(sessionService.login(req), HttpStatus.OK);  }}

references

https://github.com/xiaoyureed/redis-login-limitation

總結

以上所述是小編給大家介紹的redis 實現登陸次數限制的思路詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
福利视频导航一区| 一区二区三区视频在线| 欧美电影在线免费观看网站| 中文字幕日韩视频| 91高潮精品免费porn| 在线看欧美日韩| 欧美限制级电影在线观看| 国产欧美日韩丝袜精品一区| 91久久久久久久久久久久久| 国产欧美在线观看| 伊人激情综合网| 国产午夜精品久久久| 亚洲电影中文字幕| 欧美精品videosex牲欧美| 成年人精品视频| 久久久久中文字幕| 一区二区欧美日韩视频| 国产精品美女久久| 欧美成人全部免费| 久久久久久久电影一区| 欧美一区亚洲一区| 午夜精品在线观看| 欧美在线中文字幕| 日韩电影在线观看中文字幕| 久久久久久久一区二区三区| 日韩女优人人人人射在线视频| 69视频在线免费观看| 亚洲va男人天堂| 国产亚洲欧洲高清| 亚洲男人天堂2023| www.99久久热国产日韩欧美.com| 久久97久久97精品免视看| 亚洲欧美另类国产| 国产精品成人在线| 91天堂在线观看| 91精品国产91久久久久| 日韩亚洲欧美中文高清在线| 国产va免费精品高清在线| 精品久久久久久久久久久久久久| 亚洲精品www久久久久久广东| 成人性生交大片免费看小说| 久久久影视精品| 国产精品毛片a∨一区二区三区|国| 欧美激情区在线播放| 欧美亚洲第一区| 狠狠干狠狠久久| 久久久在线免费观看| 视频在线观看一区二区| 亚洲一区二区三区香蕉| 国产91|九色| 韩曰欧美视频免费观看| 国产成人激情小视频| 日本免费在线精品| 久久久中精品2020中文| 黄网站色欧美视频| 久久国产精品电影| 爱福利视频一区| 欧美不卡视频一区发布| 国产精品ⅴa在线观看h| 91精品国产91久久久| 久久久亚洲欧洲日产国码aⅴ| 欧美人与性动交a欧美精品| 国产精品9999| 日本精品一区二区三区在线播放视频| 亚洲精品免费av| 日韩欧美a级成人黄色| 欧美日韩国产黄| 国产成人精品免高潮费视频| 亚洲韩国日本中文字幕| 亚洲香蕉伊综合在人在线视看| 亚洲欧美精品suv| 国产精品96久久久久久又黄又硬| 亚洲精品视频二区| 亚洲精品日韩久久久| 91性高湖久久久久久久久_久久99| 国产精品亚洲片夜色在线| 91av在线看| 日韩av网址在线观看| 久久97精品久久久久久久不卡| 欧美国产日韩中文字幕在线| 这里精品视频免费| 国产脚交av在线一区二区| 欧美国产日韩在线| 一级做a爰片久久毛片美女图片| 日韩综合视频在线观看| 亚洲欧洲在线看| 欧美性猛交xxxx黑人猛交| 91欧美视频网站| 在线成人激情黄色| 国产综合在线观看视频| 亚洲国产精久久久久久久| 欧美成人黄色小视频| www.久久草.com| 欧美日韩一区免费| 亚洲iv一区二区三区| 成人做爰www免费看视频网站| 久久99视频精品| 美女扒开尿口让男人操亚洲视频网站| 国模gogo一区二区大胆私拍| 午夜精品久久久久久久99热浪潮| 久久国产加勒比精品无码| 国产+人+亚洲| 美女av一区二区三区| 日韩av手机在线看| 精品日韩中文字幕| 亚洲va欧美va国产综合久久| 夜夜嗨av一区二区三区四区| 俺去啦;欧美日韩| 日韩av中文在线| 亚洲国产精品女人久久久| 日韩小视频在线| 欧美一区二区影院| 国内免费精品永久在线视频| 国产精品99久久99久久久二8| 日本成人精品在线| 国产精品久久久久久久av电影| 亚洲直播在线一区| 97激碰免费视频| 欧美亚洲午夜视频在线观看| 日韩的一区二区| 91在线精品视频| 国产精品夜色7777狼人| 欧美伦理91i| 欧美高清理论片| 国产精品免费观看在线| 77777少妇光屁股久久一区| 亚洲激情自拍图| 久久偷看各类女兵18女厕嘘嘘| 欧美电影免费看| 在线视频亚洲欧美| 久久久久久久久久久免费精品| 91香蕉亚洲精品| 午夜免费久久久久| 日韩成人激情在线| 欧美夫妻性生活xx| 精品久久久av| 成人欧美一区二区三区黑人| 国产精品你懂得| 日韩一二三在线视频播| 亚洲无限av看| 久久国产精品影片| 欧美大学生性色视频| www国产91| 中文字幕av日韩| 国产欧美精品日韩精品| 日韩欧美视频一区二区三区| 亚洲影院色在线观看免费| 亚洲国产欧美在线成人app| 成人精品久久av网站| 日本精品免费一区二区三区| 91精品视频免费| 国产精品视频一区国模私拍| 不卡av日日日| 欧美在线不卡区| 中文字幕欧美视频在线| 国产一区二区激情| 久久夜色精品国产亚洲aⅴ| 黄色成人在线播放| 久久免费视频这里只有精品| 精品中文字幕在线2019| 97涩涩爰在线观看亚洲| yw.139尤物在线精品视频| 久久精品视频导航| 欧美国产日韩中文字幕在线|