asp.net - 使用 HEAD 或 OPTIONS 动词代替 POST 的登录表单

标签 asp.net .net asp.net-mvc forms http

我有一个很奇怪的问题。我刚刚将一个应用程序部署到生产环境中。我有两种登录操作方法:

AccountController
   [HttpGet]Login();
   [HttpPost]Login(..);

为捕获登录信息和执行发布而呈现的表单是一种简单的表单:

<form action="/Account/Login" class=" form-horizontal" method="post" novalidate="novalidate"><input name="__RequestVerificationToken" type="hidden" value="..">
.
.
</form>

我还在 Controller 上记录未处理的操作, Controller 将消息写入事件日志。这是我看到的消息:

Protected Overrides Sub HandleUnknownAction(actionName As String)
    EventLog.WriteEntry("Application", "Controller '" + Me.GetType().Name + "' does not have an action '" + actionName + "' for a request of type '" + Me.ControllerContext.HttpContext.Request.HttpMethod + "'.")
End Sub

我看到记录了这条消息:

Controller 'AccountController' does not have an action 'Login' for a request of type 'HEAD'. Controller 'AccountController' does not have an action 'Login' for a request of type 'OPTIONS'.

知道为什么请求会以 HEAD 或 OPTIONS 形式出现吗?我不知道用户是如何尝试连接到应用程序的。

最佳答案

为确保您还应该检查随该请求记录的用户代理字符串(如果可用),但我敢打赌它是一个bot 检查您的主页(可能重定向到登录页面)。

另见 googlebot head request .我不鼓励用户代理字符串过滤,除非您想了解有关该主题的最新信息(无论如何, 机器人可能伪造搜索引擎蜘蛛的用户代理字符串)。

它们通常使用正常 GET 请求,但一些机器人(试图优化带宽使用?)首先尝试使用 HEAD选项

据我所知,您有两个选择:提供一个特定的 Controller 方法来处理它们(如果您愿意)或简单地使用 robots.txt 文件来指示机器人。即使你让一切保持原样,从安全和 SEO 的角度来看,你也不应该有任何问题(如果 HEAD 收到 405,大多数机器人将使用 GET 并且选项)。

什么是正确的做法?如果您关心,我会处理它们返回 HTTP 状态 405(不允许)。有人还建议 HTTP 状态 501(未实现)可能是正确/更好的响应。

MVC 正确地 返回 Method not allowed 对于不受支持的 Request Method 并且它还填充(强制)Allow响应中的字段(在您的情况下 Allow: GET,POST),其行为等同于此代码:

[ActionName("LogIn")]
[HttpOptions, HttpHead]
public ActionResult LogInForUnsupportedHttpMethods()
{
    return new HttpStatusCodeResult(HttpStatusCode.MethodNotAllowed);
}

如果您不使用 ASP.NET MVC 5,则没有 HttpStatusCode 枚举,您必须手动指定返回代码:new HttpStatusCodeResult(405)

但是,如果不支持 HEAD(值得注意的例子是 downforeveryoneorjustme.com),并不是每个机器人/蜘蛛/服务都能正确切换到 GET,那么您可能想要返回您的HEAD 的页面(并保留 OPTIONS 的默认行为):

// This method isn't required unless you want to return a different
// HTTP status code or to perform some special operation.
[HttpOptions, ActionName("LogIn")]
public ActionResult LogInForUnsupportedHttpMethods()
{
    return new HttpStatusCodeResult(HttpStatusCode.MethodNotAllowed);
}

[HttpGet, HttpHead]
public ActionResult LogIn() {/* ... */ }

[HttpPost]
public ActionResult LogIn(LogInModel model) {/* ... */ }

优化:如果您运行的网站流量非常高,您会定期收到许多 HEAD 请求,并且它们(以可衡量的方式)影响您的网站性能然后您可能决定为 HEAD 请求返回页面的精简版本(可能没有太多服务器端处理,并且可能没有使用客户端的东西,如 CSS 和脚本) .

关于asp.net - 使用 HEAD 或 OPTIONS 动词代替 POST 的登录表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31121165/

相关文章:

javascript - 从 javascript 调用网络服务

c# - 在 .NET 中构建业务应用程序的最佳方式

asp.net - 添加 runat ="server"会改变布局的行为

.net - 使用 LINQ to SQL 时如何抽象出持久化代码?

c# - 在 .netstandard 2 中使用哪个 HttpRequest 类?

c# - Entity Framework 7 和登录失败

asp.net - 将cookie设置为在 session 结束时过期? asp.net

c# - 使用异步/等待模式在 C# 5 中编写高度可扩展的 TCP/IP 服务器?

javascript - 如何在具有多个表单的页面上使用自动保存的局部 View ?

c# - MVC AccountController 与 IsAuthenticated false OWIN