增加管理后台登录频次校验和连续错误登录后限制登录
修改管理后台验证码生成和登录校验
1个文件已修改
24 ■■■■■ 已修改文件
ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-common/ruoyi-common-redis/src/main/java/com/ruoyi/common/redis/service/RedisService.java
@@ -11,6 +11,7 @@
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
@@ -26,6 +27,9 @@
{
    @Autowired
    public RedisTemplate redisTemplate;
    @Autowired
    public StringRedisTemplate stringRedisTemplate;
    /**
     * 缓存基本的对象,Integer、String、实体类等
@@ -61,15 +65,25 @@
     */
    public long incrementCacheValue(final String key, final long timeout, final TimeUnit timeUnit)
    {
        String scriptText = "local count = redis.call('incr', KEYS[1]); "
                + "if count == 1 then redis.call('pexpire', KEYS[1], ARGV[1]); end; return count;";
        DefaultRedisScript<Long> script = new DefaultRedisScript<>(scriptText, Long.class);
        long timeoutMillis = timeUnit.toMillis(timeout);
        Long count = (Long) redisTemplate.execute(script, Collections.singletonList(key), timeoutMillis);
        Long count = stringRedisTemplate.execute(INCREMENT_SCRIPT, Collections.singletonList(key),
                String.valueOf(timeUnit.toMillis(timeout)));
        return count == null ? 0L : count;
    }
    /**
     * INCR 并在首次写入时设置过期时间的 Lua 脚本。
     * 使用 StringRedisTemplate 执行,避免 FastJson 序列化(WriteClassName)导致
     * 参数被序列化为 JSON 对象(如 {"@type":"java.lang.Long"}),使 PEXPIRE 报
     * value is not an integer or out of range。
     */
    private static final DefaultRedisScript<Long> INCREMENT_SCRIPT = new DefaultRedisScript<>(
            "local v = redis.call('get', KEYS[1]); "
                    + "if v and not tonumber(v) then redis.call('del', KEYS[1]); end; "
                    + "local count = redis.call('incr', KEYS[1]); "
                    + "if count == 1 then redis.call('pexpire', KEYS[1], ARGV[1]); end; return count;",
            Long.class);
    /**
     * 设置有效时间
     *
     * @param key Redis键