`

http的安全方法和幂等性

 
阅读更多
最近在研究http,看到http的安全方法和幂等性部分,不太明白,尤其是“post方法是非幂等的”不理解,进过查资料,找到以下两篇有价值的文章,特转过来!
理解HTTP幂等性
转自:http://www.cnblogs.com/weidagang2046/archive/2011/06/04/2063696.html

基于HTTP协议的Web API是时下最为流行的一种分布式服务提供方式。无论是在大型互联网应用还是企业级架构中,我们都见到了越来越多的SOA或RESTful的Web API。为什么Web API如此流行呢?我认为很大程度上应归功于简单有效的HTTP协议。HTTP协议是一种分布式的面向资源的网络应用层协议,无论是服务器端提供Web服务,还是客户端消费Web服务都非常简单。再加上浏览器、Javascript、AJAX、JSON以及HTML5等技术和工具的发展,互联网应用架构设计表现出了从传统的PHP、JSP、ASP.NET等服务器端动态网页向Web API + RIA(富互联网应用)过渡的趋势。Web API专注于提供业务服务,RIA专注于用户界面和交互设计,从此两个领域的分工更加明晰。在这种趋势下,Web API设计将成为服务器端程序员的必修课。然而,正如简单的Java语言并不意味着高质量的Java程序,简单的HTTP协议也不意味着高质量的Web API。要想设计出高质量的Web API,还需要深入理解分布式系统及HTTP协议的特性。

幂等性定义

本文所要探讨的正是HTTP协议涉及到的一种重要性质:幂等性(Idempotence)。在HTTP/1.1规范中幂等性的定义是:

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.


从定义上看,HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。幂等性属于语义范畴,正如编译器只能帮助检查语法错误一样,HTTP规范也没有办法通过消息格式等语法手段来定义它,这可能是它不太受到重视的原因之一。但实际上,幂等性是分布式系统设计中十分重要的概念,而HTTP的分布式本质也决定了它在HTTP中具有重要地位。

分布式事务 vs 幂等设计

为什么需要幂等性呢?我们先从一个例子说起,假设有一个从账户取钱的远程API(可以是HTTP的,也可以不是),我们暂时用类函数的方式记为:

bool withdraw(account_id, amount)

withdraw的语义是从account_id对应的账户中扣除amount数额的钱;如果扣除成功则返回true,账户余额减少amount;如果扣除失败则返回false,账户余额不变。值得注意的是:和本地环境相比,我们不能轻易假设分布式环境的可靠性。一种典型的情况是withdraw请求已经被服务器端正确处理,但服务器端的返回结果由于网络等原因被掉丢了,导致客户端无法得知处理结果。如果是在网页上,一些不恰当的设计可能会使用户认为上一次操作失败了,然后刷新页面,这就导致了withdraw被调用两次,账户也被多扣了一次钱。如图1所示:

图1

这个问题的解决方案一是采用分布式事务,通过引入支持分布式事务的中间件来保证withdraw功能的事务性。分布式事务的优点是对于调用者很简单,复杂性都交给了中间件来管理。缺点则是一方面架构太重量级,容易被绑在特定的中间件上,不利于异构系统的集成;另一方面分布式事务虽然能保证事务的ACID性质,而但却无法提供性能和可用性的保证。

另一种更轻量级的解决方案是幂等设计。我们可以通过一些技巧把withdraw变成幂等的,比如:

int create_ticket() 
bool idempotent_withdraw(ticket_id, account_id, amount)


create_ticket的语义是获取一个服务器端生成的唯一的处理号ticket_id,它将用于标识后续的操作。idempotent_withdraw和withdraw的区别在于关联了一个ticket_id,一个ticket_id表示的操作至多只会被处理一次,每次调用都将返回第一次调用时的处理结果。这样,idempotent_withdraw就符合幂等性了,客户端就可以放心地多次调用。

基于幂等性的解决方案中一个完整的取钱流程被分解成了两个步骤:1.调用create_ticket()获取ticket_id;2.调用idempotent_withdraw(ticket_id, account_id, amount)。虽然create_ticket不是幂等的,但在这种设计下,它对系统状态的影响可以忽略,加上idempotent_withdraw是幂等的,所以任何一步由于网络等原因失败或超时,客户端都可以重试,直到获得结果。如图2所示:


图2

和分布式事务相比,幂等设计的优势在于它的轻量级,容易适应异构环境,以及性能和可用性方面。在某些性能要求比较高的应用,幂等设计往往是唯一的选择。

HTTP的幂等性

HTTP协议本身是一种面向资源的应用层协议,但对HTTP协议的使用实际上存在着两种不同的方式:一种是RESTful的,它把HTTP当成应用层协议,比较忠实地遵守了HTTP协议的各种规定;另一种是SOA的,它并没有完全把HTTP当成应用层协议,而是把HTTP协议作为了传输层协议,然后在HTTP之上建立了自己的应用层协议。本文所讨论的HTTP幂等性主要针对RESTful风格的,不过正如上一节所看到的那样,幂等性并不属于特定的协议,它是分布式系统的一种特性;所以,不论是SOA还是RESTful的Web API设计都应该考虑幂等性。下面将介绍HTTP GET、DELETE、PUT、POST四种主要方法的语义和幂等性。

HTTP GET方法用于获取资源,不应有副作用,所以是幂等的。比如:GET http://www.bank.com/account/123456,不会改变资源的状态,不论调用一次还是N次都没有副作用。请注意,这里强调的是一次和N次具有相同的副作用,而不是每次GET的结果相同。GET http://www.news.com/latest-news这个HTTP请求可能会每次得到不同的结果,但它本身并没有产生任何副作用,因而是满足幂等性的。

HTTP DELETE方法用于删除资源,有副作用,但它应该满足幂等性。比如:DELETE http://www.forum.com/article/4231,调用一次和N次对系统产生的副作用是相同的,即删掉id为4231的帖子;因此,调用者可以多次调用或刷新页面而不必担心引起错误。

比较容易混淆的是HTTP POST和PUT。POST和PUT的区别容易被简单地误认为“POST表示创建资源,PUT表示更新资源”;而实际上,二者均可用于创建资源,更为本质的差别是在幂等性方面。在HTTP规范中对POST和PUT是这样定义的:

The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line ...... If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header.

The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI.


POST所对应的URI并非创建的资源本身,而是资源的接收者。比如:POST http://www.forum.com/articles的语义是在http://www.forum.com/articles下创建一篇帖子,HTTP响应中应包含帖子的创建状态以及帖子的URI。两次相同的POST请求会在服务器端创建两份资源,它们具有不同的URI;所以,POST方法不具备幂等性。而PUT所对应的URI是要创建或更新的资源本身。比如:PUT http://www.forum/articles/4231的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次PUT是相同的;因此,PUT方法具有幂等性。

在介绍了几种操作的语义和幂等性之后,我们来看看如何通过Web API的形式实现前面所提到的取款功能。很简单,用POST /tickets来实现create_ticket;用PUT /accounts/account_id/ticket_id&amount=xxx来实现idempotent_withdraw。值得注意的是严格来讲amount参数不应该作为URI的一部分,真正的URI应该是/accounts/account_id/ticket_id,而amount应该放在请求的body中。这种模式可以应用于很多场合,比如:论坛网站中防止意外的重复发帖。

总结
上面简单介绍了幂等性的概念,用幂等设计取代分布式事务的方法,以及HTTP主要方法的语义和幂等性特征。其实,如果要追根溯源,幂等性是数学中的一个概念,表达的是N次变换与1次变换的结果相同,有兴趣的读者可以从Wikipedia上进一步了解

参考:http://blog.csdn.net/xyls12345/article/details/23951469
分享到:
评论

相关推荐

    P21_创建Company资源POST_P20_HTTP方法的安全性与幂等性_Routine.Api2020_2_7.rar

    P21_创建Company资源POST_P20_HTTP方法的安全性与幂等性_Routine.Api2020_2_7.rar 使用 ASP.NET Core RESTful API ReSharper ApiController 创建Company资源POST 成功后Status:201 Created time:602ms Date:Fri,...

    38_分布式系统中接口的幂等性该如何保证?比如不能重复扣款?.zip

    在分布式系统设计中,接口的幂等性是一个关键概念,尤其是在金融系统或者订单处理系统中,确保操作的唯一性和不可重复执行是至关重要的。例如,我们提到的“不能重复扣款”的需求,就直接涉及到幂等性的应用。下面将...

    互联网API接口幂等设计

    在Java开发中,通过唯一标识、状态检查、锁定资源等方法,我们可以有效地实现接口幂等性,从而提升系统的可靠性和用户体验。在实际应用中,需要根据业务需求和场景选择合适的幂等性实现策略,并注意其可能带来的挑战...

    分布式事务-幂等

    2PC的问题在于其阻塞性质和单点故障,而幂等性可以帮助减轻这些问题,因为参与者可以安全地重试确认或回滚命令。 2. 三阶段提交(3PC):在2PC的基础上增加了预提交阶段,减少了阻塞时间,但仍然存在单点故障和网络...

    Aop注解+Redis解决SpringBoot接口幂等性(源码自取)

    综上所述,通过Spring Boot的AOP注解和Redis,我们可以方便地实现接口幂等性,提高系统的安全性。这种方式易于扩展,适用于多种业务场景,且对原始接口的代码侵入性小。在实际开发中,可以根据具体需求调整幂等键的...

    浅谈高并发下接口幂等性解决方案.docx

    浅谈高并发下接口幂等性解决方案 幂等性是在编程中一个非常重要的概念,它是指一个操作,不论执行多少次,产生的效果和返回的结果都...我们可以根据不同的场景选择合适的幂等性解决方案,以确保系统的稳定性和安全性。

    分布式服务API的幂等设计方案SpringBoot+Redis拦截器实现实例.docx

    分布式服务API的幂等设计是确保系统稳定性和数据一致性的重要策略。在分布式环境中,由于网络延迟、重试机制等因素,同一个请求可能会被多次执行。幂等性要求即使接口被重复调用,其结果也应该保持不变,避免出现如...

    接口幂等性的解决方案.docx

    在IT行业中,接口幂等性是一项重要的设计原则,特别是在分布式系统和网络通信中。它确保一个操作无论执行多少次,其结果始终相同,不会对系统状态造成额外改变。这种特性对于保证系统的稳定性和可靠性至关重要,尤其...

    模逆和模幂计算与应用

    **实验设计与界面构建** 实验中,学生需要编写程序实现这些算法,并设计用户友好的界面,包括模逆和模幂运算的输入输出,素数生成,RSA和ElGamal的公私钥对生成、加密与解密功能。每个功能都应有输入、执行和输出的...

    单云服务器下的安全外包模幂运算.pdf

    为了在不共谋的前提下安全地执行模幂运算,研究者提出了多种协议和算法,它们能够在一定程度上保证数据的隐私和运算的安全性。 该论文所提出的方案在云计算和安全外包领域具有重要的参考价值和实际应用潜力。它们...

    方阵幂安全外包云计算.pdf

    方阵幂计算是一种常见的计算问题,通常涉及在数学和计算机科学领域对方阵进行多次幂运算,特别是在线性代数、图形学和数据分析等领域。然而,对于计算能力有限的用户来说,处理大维度方阵的高次幂计算是一个挑战。 ...

    电子功用-数据的防攻击方法及装置、RSA模幂运算方法、装置和电路

    在当今数字化时代,数据安全已成为全球关注的焦点,尤其是在电子技术领域,数据防...随着技术的不断发展,未来的数据安全防护也将不断进化,但上述提到的核心原则和方法无疑将继续发挥其在保障数据安全方面的重要作用。

    93丨项目实战二:设计实现一个通用的接口幂等框架(分析)1

    5. **性能和可扩展性**:在满足幂等性的同时,也要关注框架的性能和可扩展性,确保框架可以适应不同业务场景的需求。 6. **代码质量**:编写清晰、可读、可维护的代码,避免因处理超时等异常情况而引入大量补救代码...

    电信设备-抗边信道攻击的模幂方法和设备.zip

    总结来说,抗边信道攻击的模幂方法和设备是电信领域中确保信息安全的关键技术。通过优化运算过程、采用抗SCA硬件设计和实施动态监控,可以显著提升电信设备抵御边信道攻击的能力,从而保护用户数据的隐私和通信系统...

    C++RSA求幂算法 计算机信息安全课程 编程实现RSA

    RSA算法是一种非对称...对于初学者来说,理解并实现这样的代码是学习密码学和信息安全的好方法。通过实践,你可以深入理解RSA的工作原理,同时提高C++编程能力。而通过老师的满分测试,表明这个实现是正确且有效的。

    一种大数模幂的快速实现方法

    通过预计算并存储部分结果,该方法在保持传统BR算法安全性的同时,大大提高了运算效率,有效缩短了加密解密的时间。对于需要处理大量加密信息的系统而言,这种改进算法无疑具有重大的应用价值和市场潜力。

    Http协议中POST和GET方法的本质区别

    总结来说,GET和POST的主要区别在于其目的和行为:GET用于获取资源,是安全和幂等的,数据在URL中;POST用于创建或修改资源,可能改变服务器状态,数据在请求体中。在实际开发中,理解并遵循这些原则可以提高系统的...

    Web应用安全:HTTP协议GET和POST的使用区别文本.docx

    POST请求的安全性相对更高,因为它不将数据暴露在URL中,但仍然需要注意防止跨站脚本攻击(XSS)和跨站请求伪造(CSRF)等安全问题。 在Web应用安全方面,理解GET和POST的使用差异至关重要,因为它们直接关系到数据...

    本杰明:具有幂等性的副作用

    2. **使用事务**:Clojure的`ref`、`atom`、`agent`和`promise`等数据结构支持原子性操作,允许在多线程环境中安全地处理状态,确保并发操作的幂等性。 3. **利用函数式数据结构**:Clojure提供了不可变的数据结构...

    求解大型电力系统机电振荡模态的逆幂方法.pdf

    【摘要】中提到的是一种用于求解大型电力系统机电振荡模态的逆幂方法。该方法通过忽略调速器模型、负荷电动...这种方法对于电力系统的稳定性和控制策略的研究具有很高的实用价值,有助于提升电力系统的安全性和可靠性。

Global site tag (gtag.js) - Google Analytics