IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> redis防止黑客恶意攻击的简单办法 -> 正文阅读

[大数据]redis防止黑客恶意攻击的简单办法

1.在redis中放入有用户标识的key,每次用户操作时都会根据用户标识的key去匹配一下,匹配上就能操作,匹配不上就拒绝。

下面的代码是商品秒杀场景,根据用户id和商品id去生成一个标识,然后放入redis缓存中。

@Override
    public String getMd5(Integer id,Integer userid){
        //检验用户的合法性
        User user = userMapper.findById(userid);
        if(user == null) throw new RuntimeException("用户信息不存在!");
        log.info("用户信息:[{}]",user.toString());
        //检验商品的合法性
        Stock stock = stockMapper.checkStock(id);
        if(stock == null) throw new RuntimeException("商品信息不合法!");
        log.info("商品信息:[{}]",stock.toString());
        //生成hashkey
        String hashKey = "KEY_"+userid+"_"+id;
        //生成md5//这里!QS#是一个盐 随机生成
        String key = DigestUtils.md5DigestAsHex((userid+id+"!Q*jS#").getBytes());
        stringRedisTemplate.opsForValue().set(hashKey,key,3600, TimeUnit.SECONDS);
        log.info("Redis写入:[{}][{}]",hashKey,key);
        return key;
    }

用户要秒杀商品时,根据用户id和商品id去redis查找有没有对应的签名,如果有则放行,没有就抛出异常。

 @Override
    public int kill(Integer id, Integer userid, String md5) {
        //校验redis中秒杀商品是否超时
        if(!stringRedisTemplate.hasKey("killphone")){
            throw new RuntimeException("当前商品的抢购活动已经结束啦~~");
        }
        //先验证签名
        String hashKey = "KEY_"+userid+"_"+id;
        String s = stringRedisTemplate.opsForValue().get(hashKey);
        if(s==null) 
        	throw new RuntimeException("没有携带验证签名,请求不合法!");
        if(!s.equals(md5))
            throw new RuntimeException("当前请求数据不合法,请稍后再试!");
        //校验库存
        Stock stock = checkStock(id);
        //更新库存
        updateSale(stock);
        //创建订单
        return createOrder(stock);
    }

2.用redis根据用户id在一定时间范围内统计用户访问次数,超过一定次数就限制访问。

下面这个类是在redis中保存和查询用户访问次数。

@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public int saveUserCount(Integer userId) {
         //根据不同用户id生成调用次数的key
        String limitKey = "LIMIT"+"_"+userId;
        //获取redis中指定key的调用次数
        String limitNum = stringRedisTemplate.opsForValue().get(limitKey);
        int limit = -1;
        if(limitNum == null){
            //第一次调用放入redis中设置为0
            stringRedisTemplate.opsForValue().set(limitKey,"0",3600, TimeUnit.SECONDS);
         }else{
            //不是第一次调用每次+1
            limit = Integer.parseInt(limitNum)+1;
            stringRedisTemplate.opsForValue().set(limitKey,String.valueOf(limit),3600,TimeUnit.SECONDS);
        }
        return limit;
    }

    @Override
    public boolean getUserCount(Integer userId) {
        //根据userid对应key获取调用次数
        String limitKey = "LIMIT"+"_"+userId;
        //根据用户调用次数的key获取redis中调用次数
        String limitNum = stringRedisTemplate.opsForValue().get(limitKey);
        if(limitNum == null){
            //为空直接抛弃说明key出现异常
            log.error("该用户没有访问申请验证值记录,疑似异常");
            return true;
        }
        return Integer.parseInt(limitNum) > 10;//false代表没有超过,true代表超过
    }
}

当用户在一定时间内访问次数达到限制次数,就不让用户再去访问了。

//开发一个秒杀方法 乐观锁防止超卖+令牌桶算法限流+md5签名(hash接口隐藏)+单用户访问频率限制
    @GetMapping("killtokenmd5limit")
    public String killtokenmd5limit(Integer id,Integer userid,String md5){
        System.out.println("秒杀商品的id="+id);
        //加入 令牌桶的限流措施
        if(!rateLimiter.tryAcquire(3, TimeUnit.SECONDS)){
            log.info("抛弃请求:抢购失败,当前秒杀活动过于火爆,请重试");
            return "抛弃请求:抢购失败,当前秒杀活动过于火爆,请重试!";
        }
        try{
            //单用户调用接口的频率限制
            int count = userService.saveUserCount(userid);
            log.info("用户截止该次的访问次数为:[{}]",count);
            //进行调用次数的判断
            boolean isBanned = userService.getUserCount(userid);
            if(isBanned){
                log.info("购买失败,超过频率限制!");
                return "购买失败,超过频率限制!";
            }
            //根据秒杀商品id 去调用秒杀业务
            int orderId = orderService.kill(id,userid,md5);
            return "秒杀成功,订单id为:"+String.valueOf(orderId);
        }catch(Exception e){
            e.printStackTrace();
            return e.getMessage();
        }
    }
  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 13:58:47  更:2022-01-01 14:00:41 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 14:05:35-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码