Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

A detailed explanation of the idea of realizing the limit of login times by redis

2025-01-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >

Share

Shulou(Shulou.com)06/01 Report--

Title: redis-login-limitation

Use redis to achieve login times limit, note + aop, the core code is very simple.

Basic ideas

For example, the requirements you want to meet are as follows: log in to the 1min for 5 times and lock the user for 1 hour.

Then among the parameters of the login request, there will be a parameter that uniquely identifies a user, such as email / mobile number / userName.

Use this parameter as key to store redis, the corresponding value is the number of login errors, string type, and set the expiration time to 1min. When the obtained value = "4", the current request is the 5th login exception, locked.

The so-called locking is to set the corresponding value to an identifier, such as "lock", and set the expiration time to 1h.

Core code

Define an annotation to identify the method that requires login times verification

Package io.github.xiaoyureed.redispractice.anno;import java.lang.annotation.*;@Documented@Target ({ElementType.METHOD}) @ Retention (RetentionPolicy.RUNTIME) public @ interface RedisLimit {/ * identifies the parameter name, which must be one of the request parameters * / String identifier (); / * how long to monitor. If you want to limit the number of attempts to 5 within 60s, then watch=60 Unit: s * / long watch (); / * length of lock, unit: s * / long lock (); / * number of attempts in error * / int times ();}

Write the section, check and process it before and after the target method.

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); / / it seems that you can directly inject 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 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 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);}}

Use as follows:

Package io.github.xiaoyureed.redispractice.web;@RestControllerpublic class SessionResources {@ Autowired private SessionService sessionService; / * 1 min try more than 5 times, lock user 1h * / @ RedisLimit (identifier = "name", watch = 30, times = 5, lock = 10) @ RequestMapping (value = "/ session", method = RequestMethod.POST) public ResponseEntity login (@ Validated @ RequestBody LoginReq req) {return new ResponseEntity (sessionService.login (req), HttpStatus.OK);}}

References

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

Summary

The above is the detailed explanation of the idea of realizing the limit of landing times in redis introduced by the editor. I hope it will be helpful to you. If you have any questions, please leave a message for me, and the editor will reply to you in time. Thank you very much for your support to the website!

If you think this article is helpful to you, you are welcome to reprint it, please indicate the source, thank you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Database

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report