为什么ASP.NET身份中的Logout使用POST而不是GET?

参见英文答案 > Logout: GET or POST?9个
sample Identity project使用此注销:
@if (Request.IsAuthenticated) {
  using (Html.BeginForm("LogOff","Account",FormMethod.Post,new { id = "logoutForm",@class = "navbar-right" })) {
    @Html.AntiForgeryToken()
    <ul class="nav navbar-nav navbar-right">
       <li>@Html.ActionLink("Hello " + User.Identity.GetUserName() + "!","Index","Manage",routeValues: null,htmlAttributes: new { title = "Manage" })</li>
       <li><a href="javascript:document.getElementById('logoutForm').submit()">Log off</a></li>
    </ul>
  }
}

AccountController.LogOff()动作方法有一个[HttpPost].

我可以想到使用POST而不是GET的唯一原因是[ValidateAntiForgeryToken].我没有看到这个目的,我们所做的就是退出.

当然这有点矫枉过正?为什么不使用常规的GET链接?

解决方法

原因很简单,影响用户会话状态的任何事情都不应该是get动作.获取操作应仅用于 idempotent操作(即,多次调用具有相同的效果,并且不会更改状态).

如果你考虑一下,原因应该是显而易见的.浏览器可以自由缓存,甚至可以预取获取URL(许多现代浏览器也可以这样做).您不希望浏览器意外地将您注销,因为它预先获取了一个获取链接.

现在,这不是给定代码的问题,因为我认为浏览器不会预先获取与JavaScript相关联的链接(尽管我可能是错的).

更大的问题是,如果您的注销是get操作,那么任何未经过滤的用户发布数据都可能导致注销.例如,假设您的网站上有一个论坛,并且您允许发布图像.假设有人发布了src =“http:// url-to-log-off-the-site”的图片,这可能会造成很大的破坏,因为你甚至无法查看页面以删除它把你带走

另外,在给定的示例中,Anti-Forgery令牌有一个表单字段,它将被编码到GET中的URL中.您不希望这样做.

您认为使用防伪令牌有点过分是因为您不了解防伪令牌的用途.它们旨在防止攻击者接管您的会话……并且您不希望攻击者将您注销(不要太天真地认为您的站点不够重要,无法攻击,自动漫游器漫游互联网,不关心你的网站有多重要).

相关文章

引言 本文从Linux小白的视角, 在CentOS 7.x服务器上搭建一个...
引言: 多线程编程/异步编程非常复杂,有很多概念和工具需要...
一. 宏观概念 ASP.NET Core Middleware是在应用程序处理管道...
背景 在.Net和C#中运行异步代码相当简单,因为我们有时候需要...
HTTP基本认证 在HTTP中,HTTP基本认证(Basic Authenticatio...
1.Linq 执行多列排序 OrderBy的意义是按照指定顺序排序,连续...