简体   繁体   English

如何以一种不可篡改的方式确定http请求的顺序?

[英]How can I determine the order of http requests in a way that can't be tampered with?

I am designing an online game. 我正在设计一个在线游戏。 Within the game, a player makes a series of moves. 在游戏中,玩家进行了一系列动作。 Previous moves can effect moves can effect later moves. 先前的动作可能会影响后续动作。 This means the order of moves is crucial. 这意味着动作顺序至关重要。 The moves are implemented as AJAX requests. 这些移动是作为AJAX请求实现的。 My backend is expressjs with node. 我的后端是带有节点的expressjs。

I could implement moves asynchronously but there is a slight chance that earlier moves might finish after later moves. 我可以异步实现动作,但是稍稍的机会可能会在以后的动作之后完成之前的动作。 I could make sure that the move tasks are completed in the order the requests were received by chaining requests onto promises but can I guarantee that an http request made before another will arrive before another? 我可以通过将请求链接到Promise上来确保按接收请求的顺序完成移动任务,但是我可以保证在另一个请求之前发出的http请求会在另一个请求之前到达吗?

I could timestamp the moves client side and process them in that order. 我可以给移动客户端加盖时间戳,并按顺序处理它们。 My concern is that users might cheat by simulating timestamped requests, ruining the order, crashing the game if they are about to lose. 我担心的是,用户可能会通过模拟带有时间戳的请求来作弊,破坏订单,如果他们将要输掉游戏,则会使游戏崩溃。 This is because some moves will break the game if they are executed in the wrong order. 这是因为如果以错误的顺序执行某些动作会破坏游戏。

Of course I can handle this error but I can't figure out the true order of moves by checking their contents because sometimes multiple orders would be legal yet players might have more information as the make certain moves so it is crucial that the true order is executed. 当然我可以解决这个错误,但我无法通过检查其内容来确定动作的真实顺序,因为有时多个顺序是合法的,但玩家在做出某些动作时可能会获得更多信息,因此至关重要的是被执行。 Even though the game wouldn't actually crash it would be impossible to determine the true order. 即使游戏实际上不会崩溃,也无法确定真正的顺序。 Even if I include the entire gamestate in each request it is still potentially spoofable. 即使我在每个请求中都包含了整个游戏状态,它仍然可能是可欺骗的。

Is there some way I can determine the order of http requests in a way that users can't tamper with? 有什么方法可以确定用户无法篡改的http请求的顺序? I can't see another solution to this problem. 我看不到此问题的另一种解决方案。

It's really not clear what problem you're trying to solve. 目前还不清楚您要解决什么问题。 It is very simple to code a client to make a bunch of http requests and to then process them in the order they were sent (regardless of the order the responses were received). 对客户端进行编码以发出一堆http请求,然后以它们发送的顺序(无论接收响应的顺序如何)进行处理是非常简单的。 A simple combination of any promise-driven ajax call (such as jQuery) and Promise.all() will do that for you if you are sending multiple requests at the same time. 如果您要同时发送多个请求,则任何由promise驱动的ajax调用(例如jQuery)和Promise.all()的简单组合Promise.all()以为您完成此任务。

If you are not sending them at the same time, such that you might send a request, a little later send another request (but before previous response is back), then send some more requests, etc..., then you can just create a queue for responses. 如果您不是同时发送它们,例如您可能发送一个请求,稍后再发送另一个请求(但在返回之前的响应之前),然后发送更多的请求,等等,那么您可以创建响应队列。 Each Ajax call is tied to a queue entry. 每个Ajax调用都绑定到一个队列条目。 When the response comes back the response goes into the queue entry. 当响应返回时,响应进入队列条目。 Each time you get a response, you process the oldest items in the queue that you have responses for and you process them in the order of the queue. 每次收到响应时,都会处理您有响应的队列中最旧的项目,并按照队列的顺序进行处理。 This allows you to do random send time requests, but always process responses in order. 这允许您执行随机发送时间请求,但始终按顺序处理响应。

Since all of this ordering is done client-side, it is not tamperproof (nothing done client-side is tamperproof), but it would require actual modification of the Javascript or the queue data structure, not just modifying a response in order to change the order of processing. 由于所有这些排序都是在客户端完成的,因此它不是防篡改的(客户端没有做任何事情都是防篡改的),但是它需要对Javascript或队列数据结构进行实际修改,而不仅仅是修改响应才能更改处理顺序。 To makes things more tamperproof, you have to move more decision making to the server where it can't be tampered with. 为了使事情变得更加防篡改,您必须将更多的决策权移到不可篡改的服务器上。

Here's a simple promise-based ajax queue that lets you send as many requests as you want and guarantees that the responses will be processed in order. 这是一个简单的基于promise的ajax队列,它使您可以发送任意数量的请求,并保证响应将按顺序处理。

var queueAjax = (function() {
    var lastAjax = Promise.resolve();

    return function (url, options) {
        // chain to the prior promise so this won't get resolved until all prior items
        // in the queue have been fulfilled in some way
        var priorPromise = lastAjax.catch(function() {
            // always fulfilled
            return;
        });
        var ajaxPromise = doAjax(url, options).then(function(val) {
            return {val: val};
        }, function(err) {
            return {err: err};
        });
        lastAjax = Promise.all([ajaxPromise, priorPromise]).then(function(results) {
            var result = results[0];
            // if there was an error, then throw to reject with that err
            if (result.hasOwnProperty("err")) {
                throw err;
            } else {
                return result.val;
            }
        });
        return lastAjax;
    }
})();

// sample usage
queueAjax(someUrl, someOptions).then(function(val) {
    // process results
});

queueAjax(someUrl2, someOptions2).then(function(val) {
    // process results
});

queueAjax(someUrl3, someOptions3).then(function(val) {
    // process results
});

This queuing system function sends the ajax requests in parallel, but makes sure their .then() handlers are called in the order the requests were sent. 该排队系统函数并行发送ajax请求,但确保以发送请求的顺序调用其.then()处理函数。 Unlike Promise.all() , you can add new requests to the queue at any time and they will just be added to the sequence. Promise.all()不同,您可以随时将新请求添加到队列中,而这些新请求只会被添加到序列中。

Here's a working demo: https://jsfiddle.net/jfriend00/7r2j1qme/ 这是一个工作示例: https : //jsfiddle.net/jfriend00/7r2j1qme/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM