zoukankan      html  css  js  c++  java
  • 秒杀接口地址的隐藏

     问题:秒杀页面中如果商品秒杀链接要是提前暴露出去可能有人直接访问url就提前秒杀了

     解决:做个时间校验不就可以解决了吗?没到秒杀时间不给秒杀。这种方案也存在问题,既然我知道了秒杀请求链接,那我通过程序不断获取最新的北京时间,可以达到毫秒级别的,我就在00毫秒的时候请求,我敢说绝对比你人工点的成功率大太多了,而且我可以一毫秒发送N次请求,搞不好你卖100个产品我全拿了。

     那这种情况怎么避免?

      简单,把URL动态化,就连写代码的人都不知道,你就通过MD5之类的加密算法加密随机的字符串去做url,然后通过前端代码获取url后台校验才能通过。  

    怎么实现逻辑?

    思路:

      1.在进行秒杀之前,先请求一个服务端地址,/getmiaoshaPath 这个地址,用来获取秒杀地址,传参为 商品id,在服务端生成随机数(MD5)作为pathId存入缓存,(缓存过期时间60s),然后将这个随机数返回给前端.

      2.获得该pathid,后 前端在用这个pathid拼接在Url上作为参数,去请求domiaosha服务

      3.后端接收到这个pathid 参数,并且与 缓存中的pathid 比较。

      如果通过比较,进行秒杀逻辑,如果不通过,抛出业务异常,非法请求。

    /*点击秒杀之后 就访问后端 获取一个秒杀地址pathId*/
    function getMiaoshaPath() {
        $.ajax({
            url :"/miaosha/getPath",
            type : "GET",
            data:{
                goodsId :$("#goodsId").val(),
                verifyCode : $("#verifyCode").val()
            },
            success:function(data){
                if (data.code ==0) {//
                    var path = data.data
                    domiaosha(path)
                }else {
                    layer.msg(data.message)
                }
            },
            error :function () {
                layer.msg("客户端错误")
            }
        })
     
    }
     
        function domiaosha(path){
            $.ajax({
                url :"/miaosha/"+path+"/do_miaosha",//安全优化,带着这个path去访问
                type : "POST",
                data:{
                    goodsId :$("#goodsId").val()
                },
                success:function(data){
                    if (data.code ==0) {//成功 就跳转 订单页面 并传入 orderid
                        // window.location.href= "/order_detail.htm?orderId="+data.data.id;
                        //若果返回成功,即表示收到请求,等待中
                        getMiaoshaResult($("#goodsId").val());
                    }else {
                        layer.msg(data.message)
                    }
                },
                error :function () {
                    layer.msg("客户端错误")
                }
            })
        }
    /**
         * 安全优化之 ---接口地址随机化(隐藏)
         * 1.点击秒杀之后,先访问该接口生成一个pathId,并存入redis 返回前端
         * 2.前端带着这个pathId去访问秒杀接口,如果传入的path和从redis取出的不一致,就认为 非法请求
         */
        @AccessLimit(seconds = 5,maxCount = 5,needLogin = true)
        @RequestMapping(value = "/getPath", method = RequestMethod.GET)
        @ResponseBody
        public Result<String> getPath(HttpServletRequest request,MiaoshaUser user, Model model,
                                      @RequestParam("goodsId") long goodsId,
                                      @RequestParam(value = "verifyCode")String verifyCode) {
            if (user == null) {
                return Result.error(CodeMsg.SESSION_ERROR);
            }
     
     
            String str = UUIDUtill.uuid();
            /*随机生成 一个 pathId 返回给前端*/
            String pathId = Md5Util.md5(str + "1111");
            redisService.set(MiaoshaKey.getMiaoshaPath, "" + user.getId() + goodsId, pathId);
    /**
         * URL md5加密
         * @param url
         * @return
         */
        public static String Md5ForUrl(String url) {
            try {
                MessageDigest md5 = MessageDigest.getInstance("MD5");
                md5.update(url.getBytes("UTF-8"));
                byte[] b = md5.digest();
                
                int i;
                StringBuffer buf = new StringBuffer();
                for(int offset = 0, len = b.length; offset < len; offset++) {
                    i = b[offset];
                    if(i < 0) {
                        i += 256;
                    }
                    if(i < 16) {
                        buf.append("0");
                    }
                    buf.append(Integer.toHexString(i));
                }
                url = buf.toString();
                System.out.println("result = " + url);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return url;
        }

      该操作:可以为了防止,恶意用户登陆之后,获取token的情况下,通过不断调用秒杀地址接口,来达到刷单的恶意请求。

      每次的url都不一样,只有真正点击秒杀按钮,才会根据商品和用户id生成对应的秒杀接口地址。

      但是,这种情况仍然不能解决 利用 按键精灵或者 机器人 频繁点击按钮的操作,为了降低点击按钮的次数,以及高并发下,防止多个用户在同一时间内,并发出大量请求,加入数学公式图形验证码等防高并发优化。

  • 相关阅读:
    Mysql
    JavaScript常用事件
    css
    HTML
    判断pc还是手机打开跳转到别的网页
    queue 队列
    兼容firstChild和firstElementChild
    总结各种width,height,top,left
    原生js提取非行间样式
    ie8 不支持media
  • 原文地址:https://www.cnblogs.com/myseries/p/11891132.html
Copyright © 2011-2022 走看看