当前位置:网站首页>Redis - Use lua script to control the number of wrong passwords and lock the account

Redis - Use lua script to control the number of wrong passwords and lock the account

2022-08-10 23:18:00 Technical log

Lua script: It is a Redis scripting language with similar functions to pipelines. The client can send multiple statements to the server in batches; however, the statements sent by the Lua script are atomic, and the pipelineSent statements are not atomic.

Lua script code: Store the code in resource --> loginFailLimit.lua file;

local key = KEYS[1]local limit = tonumber(ARGV[1]) ----> the number of times to set the limitlocal limitTime = tonumber(ARGV[2]) ----> Set the time limitlocal lockTime = tonumber(ARGV[3]) ----> account lock timelocal current = tonumber(redis.call('get', key) or '0')-- Incorrect limit times per limitTime, the account will be locked for lockTime time;if(current == 0) thenredis.call('incrBy', key, "1");redis.call('expire', key, limitTime);return 0;elseif (current < limit) thenredis.call('incrBy', key, "1");return 0;elseif (current == limit) thenredis.call('incrBy', key, "1");redis.call('expire', key, lockTime);return 1;elsereturn 1;end;

Configure DefautRedisScript:

 @Beanpublic DefaultRedisScript redisScript() {DefaultRedisScript objectDefaultRedisScript = new DefaultRedisScript<>();objectDefaultRedisScript.setResultType(Boolean.class);objectDefaultRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("loginFailLimit.lua")));return objectDefaultRedisScript;}
Create constant class:
public class RedisConstant {public final static String LIMIT = "5"; //Lock after n failures:public final static String LIMIT_TIME = "600"; //Time range: unit/secondpublic final static String LOCK_TIME = "600"; //Account lock time: unit/second}

Create RedisUtil tool class:

@Componentpublic class RedisUtil {@Autowiredprivate RedisTemplate redisTemplate;@Autowiredprivate DefaultRedisScript redisScript;/*** Get key lock status:* @param key* @return true - locked; false - unlocked;*/public Boolean getLockState(String key) {return (Boolean) redisTemplate.execute(redisScript,Arrays.asList(key),RedisConstant.LIMIT, RedisConstant.LIMIT_TIME, RedisConstant.LOCK_TIME);}/*** Get the remaining lock time of the key:* @param key* @return*/public long getLockInvalidTime(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** Get the value of key:* @param key* @return*/public String getValueByKey(String key) {return redisTemplate.opsForValue().get(key);}}

Test:

@SpringBootTestclass RedisLuaApplicationTests {@Autowiredprivate RedisUtil redisUtil;final String LOGIN_KEY = "PASSWORD_ERROR_KEY_";@Testvoid contextLoads() {//Simulate password error:if (true){String key = LOGIN_KEY + "userId";Boolean flag = redisUtil.getLockState(key);if (flag){long lockInvalidTime = redisUtil.getLockInvalidTime(key);System.out.println("The password is frequently incorrect and has been locked! Please log in again after "+lockInvalidTime+" seconds or contact the system administrator!");return;}String value = redisUtil.getValueByKey(key);int i = Integer.parseInt(RedisConstant.LIMIT) - Integer.parseInt(value);System.out.println("Wrong password, remaining "+i+" chance");return;}}}

原网站

版权声明
本文为[Technical log]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/222/202208102228443767.html