热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

简单秒杀系统中的接口隐藏(安全验证)

为什么要安全验证?对于稍微懂一些电脑的人可以通过抓包方式F12获取秒杀的接口地址,如果有些人根据此自己写了一个脚本进行抢购,如果有人根据获取到的接口写了一个抢购的脚本,那么就可以通

为什么要安全验证?


对于稍微懂一些电脑的人可以通过抓包方式F12获取秒杀的接口地址,如果有些人根据此自己写了一个脚本进行抢购,如果有人根据获取到的接口写了一个抢购的脚本,那么就可以通过不在app界面点击下单按钮就可以下单了,速度比点击下单按钮快得多。所以对于一些用户来说不公平。

安全验证流程?


       用户在下单前,先发出一个生成md5hash值的请求,根据自己抢购的商品id和自己的用户Id用Md5加密算法和随机盐生成一个hash值存到redis中,在redis中设置过期时间,等用户真正下单时发起的下单请求(秒杀请求)携带着Md5的hash值和redis中已经存在的hash值作比较是否相等,就能判断此请求是根据脚本发起的请求(没有点击抢购秒杀按钮)还是用户在app下下的单了,避免一些用户的脚本抢购,如果两次md5的值相等,那么就处理下单业务,如果不相等,那么就抛弃请求。

               

controller.java

             

                

 md5算法-----service.java


/**** @param id 商品id* @param userId 用户id* @return*/@Overridepublic String getMd5(Integer id, Integer userId) {//验证Userid 存在用户信息User user = userDao.findById(userId);if(user == null){log.info("用户信息: [{}]",user);throw new RuntimeException("用户信息不存在");}//验证id 存在商品信息Stock stock = stockDao.checkStock(id);if(stock == null){//sout打印log.info("商品信息: [{}]",stock.toString());throw new RuntimeException("商品信息不合法");}String hashKey = "KEY_" + userId + "_" +id; //这里!QS#是一个盐 随机生成//生成md5签名放入redis服务String value = DigestUtils.md5DigestAsHex((userId + id + "!Q*jS#").getBytes());stringRedisTemplate.opsForValue().set(hashKey,value,120, TimeUnit.SECONDS);log.info("redis写入: [{}] [{}]",hashKey,value);return value;}

秒杀------service.java


@Overridepublic int killMd5(Integer id, Integer userId, String md5) {//校验redis中秒杀商品是否超时Boolean hasKey = stringRedisTemplate.hasKey("kill"+id);if(!hasKey){throw new RuntimeException("当前商品的抢购时间已截止");}//先验证签名//从redis中获取签名String hashKey = "KEY_" + userId + "_" +id; //这里!QS#是一个盐 随机生成String value = stringRedisTemplate.opsForValue().get(hashKey);//判断redis是否为空if("".equals(value)){throw new RuntimeException("没有携带验证签名,当前请求不合法");}if(!value.equals(md5)){//证明不是同一个用户throw new RuntimeException("当前数据不合法,请稍后再试");}//校验库存Stock stock = checkStock(id);//更新库存updateSale(stock);//创建订单int orderId = createOrder(stock);return orderId;}

不太会,会的时候再继续补充


推荐阅读
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 本文详细介绍了PHP中的几种超全局变量,包括$GLOBAL、$_SERVER、$_POST、$_GET等,并探讨了AJAX的工作原理及其优缺点。通过具体示例,帮助读者更好地理解和应用这些技术。 ... [详细]
  • 使用 Babylon.js 实现地球模型与切片地图交互(第三部分)
    本文继续探讨在上一章节中构建的地球模型基础上,如何通过自定义的 `CameraEarthWheelControl` 类来实现更精细的地图缩放控制。我们将深入解析该类的实现细节,并展示其在实际项目中的应用。 ... [详细]
  • 使用jQuery与百度地图API实现地址转经纬度功能
    本文详细介绍了如何利用jQuery和百度地图API将地址转换为经纬度,包括申请API密钥、页面构建及核心代码实现。 ... [详细]
  • 本文介绍如何通过Java代码调用阿里云短信服务API来实现短信验证码的发送功能,包括必要的依赖添加和关键代码示例。 ... [详细]
  • 使用 ModelAttribute 实现页面数据自动填充
    本文介绍了如何利用 Spring MVC 中的 ModelAttribute 注解,在页面跳转后自动填充表单数据。主要探讨了两种实现方法及其背后的原理。 ... [详细]
  • 本文详细对比了HashMap和HashTable在多线程环境下的安全性、对null值的支持、性能表现以及方法同步等方面的特点,帮助开发者根据具体需求选择合适的数据结构。 ... [详细]
  • Java高级工程师学习路径及面试准备指南
    本文基于一位朋友的PDF面试经验整理,涵盖了Java高级工程师所需掌握的核心知识点,包括数据结构与算法、计算机网络、数据库、操作系统等多个方面,并提供了详细的参考资料和学习建议。 ... [详细]
  • selenium通过JS语法操作页面元素
    做过web测试的小伙伴们都知道,web元素现在很多是JS写的,那么既然是JS写的,可以通过JS语言去操作页面,来帮助我们操作一些selenium不能覆盖的功能。问题来了我们能否通过 ... [详细]
  • 本文介绍了如何通过安装和配置php_uploadprogress扩展来实现文件上传时的进度条显示功能。通过一个简单的示例,详细解释了从安装扩展到编写具体代码的全过程。 ... [详细]
  • 本文详细介绍了 Redis 中的主要数据类型,包括 String、Hash、List、Set、ZSet、Geo 和 HyperLogLog,并提供了每种类型的基本操作命令和应用场景。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • 本文介绍如何使用JavaScript中的for循环来创建一个九九乘法表,适合初学者学习循环结构的应用。 ... [详细]
  • 根据官方定义,RxJava是一种用于异步编程和可观察数据流的API。其核心特性在于流式处理能力和丰富的操作符支持。 ... [详细]
author-avatar
jzcpojwmds_652
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有