美文网首页
如何防止 HTTP 重复请求

如何防止 HTTP 重复请求

作者: onizuka_jp | 来源:发表于2017-03-25 16:46 被阅读402次

    背景

    之前就在电信叠加卡系统中发现一个问题,即有部分号码在很短的时间内订购多次同种套餐,并扣除同等金额。本以为是前端在提交后没有 disable 掉提交按钮所导致的客户多次点击重复提交。但今天,即 2017 年 3 月 25 日,再次发现一个号码发生这种情况,在短短 10 秒内,连续提交了 5 次订单。

    目标

    • 发现为什么出现这种现象;
    • 如何避免该情况;

    问题分析

    当前正常访问流程

    客户端 -> Cloudflare 反向代理 -> 我自己的服务器 Nginx 反向代理 -> 应用服务器 Express 应用

    问题可能存在的节点

    每一个箭头代表一次访问,每次访问过程都可能出现多次请求的问题。

    相关日志

    数据库订购记录:

    /* 1 createdAt:2017/3/25 上午11:07:43*/
    {
        "_id" : ObjectId("58d5deff6d592135e91b4191"),
        "updatedAt" : ISODate("2017-03-25T11:07:43.260+08:00"),
        "createdAt" : ISODate("2017-03-25T11:07:43.260+08:00"),
        "simcardNo" : "1459207",
        "_packId" : ObjectId("5853b3f6c9e333027664b3c1")
    },
    
    /* 2 createdAt:2017/3/25 上午11:07:43*/
    {
        "_id" : ObjectId("58d5deff6d592135e91b4192"),
        "updatedAt" : ISODate("2017-03-25T11:07:43.724+08:00"),
        "createdAt" : ISODate("2017-03-25T11:07:43.724+08:00"),
        "simcardNo" : "1459207",
        "_packId" : ObjectId("5853b3f6c9e333027664b3c1")
    },
    
    /* 3 createdAt:2017/3/25 上午11:07:44*/
    {
        "_id" : ObjectId("58d5df006d592135e91b4193"),
        "updatedAt" : ISODate("2017-03-25T11:07:44.088+08:00"),
        "createdAt" : ISODate("2017-03-25T11:07:44.088+08:00"),
        "simcardNo" : "1459207",
        "_packId" : ObjectId("5853b3f6c9e333027664b3c1")
    },
    
    /* 4 createdAt:2017/3/25 上午11:07:44*/
    {
        "_id" : ObjectId("58d5df006d592135e91b4194"),
        "updatedAt" : ISODate("2017-03-25T11:07:44.845+08:00"),
        "createdAt" : ISODate("2017-03-25T11:07:44.845+08:00"),
        "simcardNo" : "1459207",
        "_packId" : ObjectId("5853b3f6c9e333027664b3c1")
    },
    
    /* 5 createdAt:2017/3/25 上午11:07:55*/
    {
        "_id" : ObjectId("58d5df0b6d592135e91b4195"),
        "updatedAt" : ISODate("2017-03-25T11:07:55.153+08:00"),
        "createdAt" : ISODate("2017-03-25T11:07:55.153+08:00"),
        "simcardNo" : "1459207",
        "_packId" : ObjectId("5853b3f6c9e333027664b3c1")
    }
    

    我自己的服务器 Nginx 反向代理的日志文件:

    172.68.141.158 - - [25/Mar/2017:11:02:18 +0800] "OPTIONS /accounts HTTP/1.1" 204 0 "http://fp.m2m-10000.cn/bind/1459207"
    172.68.141.158 - - [25/Mar/2017:11:02:19 +0800] "PATCH /accounts HTTP/1.1" 200 35 "http://fp.m2m-10000.cn/bind/1459207"
    172.68.141.158 - - [25/Mar/2017:11:02:19 +0800] "PATCH /accounts HTTP/1.1" 200 35 "http://fp.m2m-10000.cn/bind/1459207"
    172.68.141.158 - - [25/Mar/2017:11:02:20 +0800] "PATCH /accounts HTTP/1.1" 200 35 "http://fp.m2m-10000.cn/bind/1459207"
    172.68.141.158 - - [25/Mar/2017:11:02:21 +0800] "PATCH /accounts HTTP/1.1" 200 35 "http://fp.m2m-10000.cn/bind/1459207"
    172.68.141.158 - - [25/Mar/2017:11:02:31 +0800] "PATCH /accounts HTTP/1.1" 200 35 "http://fp.m2m-10000.cn/bind/1459207"

    从该日志可以分析出,第二次访问的时候就产生的多次异常的 http 请求。问题只可能发生在两个地方,要么客户端多次访问 Cloudflare 服务器,要么 Cloudflare 多次访问我的 Nginx 服务器。

    后来又做了一个小的项目,最简单的一个留言板的应用,结果发现很多记录都被重复提交了 6、7 次。

    相关文章

      网友评论

          本文标题:如何防止 HTTP 重复请求

          本文链接:https://www.haomeiwen.com/subject/mejcottx.html