为什么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中.您不希望这样做.

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

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....