当重定向到登录页面时,正确的 HTTP状态码是什么?

当用户没有登录而试图访问需要登录的页面时,重定向到登录页面的正确 HTTP状态码是什么?

我这样问是因为 由 W3C 设置的3xx 响应代码 看起来都不符合要求:

10.3.1300选择题

请求的资源对应于 一系列表述中的任何一种, 每个都有自己特定的位置, 以及代理人主导的谈判 (第12条) 提供,以便用户(或用户) 代理)可以选择首选的 表示和重定向其 请求到该位置。

除非是校长的要求 回应应该包括一个实体 包含资源列表的 的特征及位置 用户或用户代理可以 选择一个最合适的 实体格式由 内容类型中给定的媒体类型 头字段。取决于 格式和能力

用户代理,选择最多 可以进行适当的选择 自动。但是,这个 规范没有定义任何 这种自动选择的标准。

如果服务器有首选项,则为 代表性,应该包括 特定的 URI 在位置字段中的表示; 用户代理可以使用 Location 字段 自动重定向的值 除非指示,否则响应是可缓存的 否则。

10.3.2301永久性迁移

请求的资源已被 分配一个新的永久 URI 和任何 未来对此资源的引用 应该使用返回的 URI 之一。 具有链接编辑能力的客户端 应该自动重新连接 对请求 URI 的引用 或返回的更多新引用 服务器,如果可能的话。这 除非指示,否则响应是可缓存的 否则。

应给予新的永久 URI 通过响应中的 Location 字段。 除非请求方法是 HEAD, 回应的实体应该 包含一个简短的超文本说明 新 URI 的超连结。

中接收到301状态码 对 GET 以外的请求的响应 或者 HEAD,用户代理不能 自动重定向请求 除非能得到环境保护署的确认 用户,因为这可能会更改 请求的条件 已发出。

  Note: When automatically redirecting a POST request after
receiving a 301 status code, some existing HTTP/1.0 user agents
will erroneously change it into a GET request.

10.3.3发现302

请求的资源驻留在 暂时使用不同的 URI。 因为重定向可能会改变 有时候,客户应该 继续使用 Request-URI 未来的要求。这个回应只是 如果由 缓存-控制或过期头字段。

临时 URI 应由 响应中的 Location 字段。 除非请求方法是 HEAD, 回应的实体应该 包含一个简短的超文本说明 新 URI 的超连结。

中接收到302状态码 对 GET 以外的请求的响应 或者 HEAD,用户代理不能 自动重定向请求 除非能得到环境保护署的确认 用户,因为这可能会更改 请求的条件 已发出。

  Note: RFC 1945 and RFC 2068 specify that the client is not allowed
to change the method on the redirected request.  However, most
existing user agent implementations treat 302 as if it

是303 则对 Location 字段-value 执行 GET 状态代码303和307具有 被添加的服务器,希望明确说明哪些 客户应该有这样的反应。

10.3.4303见其他

对请求的响应可以是 在不同的 URI 下找到 上使用 GET 方法检索 这个方法存在 主要是为了允许输出 POST 激活的脚本重定向 所选资源的用户代理 New URI 不是替代引用 获取最初请求的资源。 不能缓存303响应, 而是对第二个的反应 (重定向)请求可能是 可缓存的。

不同的 URI 应该由 响应中的 Location 字段。 除非请求方法是 HEAD, 回应的实体应该 包含一个简短的超文本说明 新 URI 的超连结。

  Note: Many pre-HTTP/1.1 user agents do not understand the 303
status. When interoperability with such clients is a concern, the
302 status code may be used instead, since most user agents react
to a 302 response as described here for 303.

10.3.5304未经修改

如果客户端已执行 条件 GET 请求和访问是 但该文件并没有 修改,服务器应该响应 用这个状态码304 答复必须不包含 消息体,因此总是 以第一个空行结束 在标题字段之后。

响应必须包括 以下标题字段:

  - Date, unless its omission is required by section 14.18.1 If a

无时钟原始服务器服从这些 规则,代理和客户端添加 对任何回应的日期 收到没有一个(因为已经 [ RFC 2068] ,第 14.19) ,缓存将正常运行。

  - ETag and/or Content-Location, if the header would have been sent
in a 200 response to the same request
- Expires, Cache-Control, and/or Vary, if the field-value might
differ from that sent in any previous response for the same
variant If the conditional GET used a strong cache validator (see

第13.3.3节) ,回应应 不包括其他实体头。 否则(即,条件 GET 使用弱验证程序) ,响应 不能包括其他实体头; 这可以防止 缓存的实体-主体和更新 标题。

如果304响应表示一个实体 当前没有缓存,那么缓存 必须无视反应和重复 无条件的要求。

如果缓存使用接收到的304 响应以更新缓存条目,则 缓存必须更新条目以反映 中给出的任何新字段值 回应。

10.3.6305使用代理服务器

请求的资源必须是 通过给定的代理访问 位置字段。位置字段 给出代理的 URI 预计收件人将重复这一点 通过代理发出的单个请求 回应必须只能由 原始服务器。

  Note: RFC 2068 was not clear that 305 was intended to redirect a
single request, and to be generated by origin servers only.  Not
observing these limitations has significant security consequences.

10.3.7306(未使用)

中使用了306状态代码 以前版本的规范, 不再使用,而代码是 保留意见。

10.3.8307临时转接

请求的资源驻留在 暂时使用不同的 URI。 因为重定向可能被改变 有时候,客户应该 继续使用 Request-URI 未来的要求。这个回应只是 如果由 缓存-控制或过期头字段。

临时 URI 应由 响应中的 Location 字段。 除非请求方法是 HEAD, 回应的实体应该 包含一个简短的超文本说明 超连结至新的 URI,因为 许多 HTTP/1.1之前的用户代理都没有 了解307的情况。因此, 注释应该包含 必要的信息 重复新的原始请求 URI.

中接收到307状态码 对 GET 以外的请求的响应 或者 HEAD,用户代理不能 自动重定向请求 除非能得到环境保护署的确认 用户,因为这可能会更改 请求的条件 已发出。

我现在使用302,直到我找到 的正确答案。

最新消息及结论:

HTTP 302更好,因为它与客户端/浏览器具有最好的兼容性。

70072 次浏览

我觉得是 303看其他 302发现:

请求的资源暂时驻留在不同的 URI 下。自从重定向 可能偶尔会改变以来,客户端应该继续使用 Request-URI 来处理未来的请求。此响应只有在缓存控件或过期头字段指示时才可缓存。

在我看来最适合登录页面。我最初考虑的 303 see other将工作得一样好。经过一番思考,我认为 302 Found更合适,因为找到了所请求的资源 曾经是,在访问它之前还有另一个页面要浏览。默认情况下响应不会被缓存,这也很好。

我认为适当的解决方案是 HTTP401(未授权)头。

Http://en.wikipedia.org/wiki/http_codes#4xx_client_error

这个标题的目的正是如此。但是,正确的过程应该是这样的,而不是重定向到登录页面:

  • 未登录的用户尝试访问受登录限制的页面。
  • 系统标识用户未被记录
  • System 返回 HTTP 401头,并在相同的响应中显示登录表单(不是重定向)。

这是一个很好的实践,比如提供一个有用的404页面、站点地图链接和搜索表单。

再见。

这是对 HTTP 重定向机制的误用。如果用户没有被授权,那么你的应用程序必须返回 401 Unauthorized。如果用户被授权,但是不能访问请求的资源,那么必须返回 403 Forbidden

您应该在客户端执行重定向,例如通过 javascript。重定向的状态代码,因为不存在所需的授权.为此使用30x 不符合 HTTP。

如何思考 HTTP 状态码

未授权触发 HTTP 的请求身份验证机制。

401 Unauthorized状态码要求有支持各种身份验证类型的 WWW-Authenticate头:

WWW-身份验证: < type > 碰撞域 = < 碰撞域 >

承载、 OAuth、基础、摘要、饼干等

这里有很多令人信服和矛盾的回答! 如何选择?

入围名单:

发现302号

指示请求的资源已被 暂时移动到由位置标头给出的 URL 重定向到这个页面,但搜索引擎不会更新它们的链接到 资源。

规范要求方法(和主体)不是 当执行重定向时更改,但不是所有用户代理 顺应。它 因此,建议仅将302代码设置为响应 方法,并改为使用307临时重定向,作为 在这种情况下,方法更改是明确禁止的。 Https://developer.mozilla.org/en-us/docs/web/http/status/302

含糊不清,可能有 bug,也可能过时,但是可以工作,特别是对 GET 请求。

307临时重定向

请求的资源已暂时移动到 位置标头。

307和302的唯一区别就是307保证了这一点 方法和主体在重定向时不会被更改 使用302时,一些旧客户端错误地更改了 GET 方法: 非 GET 方法和302的行为是 在网络上无法预测,而307的行为 对于 GET 请求,它们的行为是相同的。 Https://developer.mozilla.org/en-us/docs/web/http/status/307

我最初的想法是,如果您的应用程序支持 HTTP 1.1 + ,那么这将是一种更新、更清晰的进行临时重定向的方法。

未经授权

指示客户端请求尚未完成,因为 缺少所请求资源的有效身份验证凭据。

此状态代码与 HTTPWWW-Authenticate 响应头一起发送 包含有关客户端如何请求 在提示用户进行身份验证后,再次使用 证件。

此状态代码类似于403禁止状态代码,除了 在导致这个状态码的情况下,用户身份验证 可以允许访问资源。

我同意这可能是正确的反应代码说,“直到您登录。”但是几乎每个 webapp 都使用带 Cookie 的 HTML 表单来登录,而且这个 HTTP 代码不允许“ Cookie”作为身份验证方案: Https://developer.mozilla.org/en-us/docs/web/http/headers/www-authenticate 还有 Https://www.iana.org/assignments/http-authschemes/http-authschemes.xhtml

一些人指出,有人在2009年起草了一个“ Cookie”计划: WWW-Authenticate Cookie Https://datatracker.ietf.org/doc/html/draft-broyer-http-cookie-auth-00 - 不知道为什么没有成功-也许是因为超出了 HTTP 的范围?

如果没有“ Cookie”作为选项,我认为这不适合基于 HTML 和 Cookie 的身份验证。

调查

在没有一个不可否认的单一“正确”答案的情况下,我研究了一些行业领袖正在做的事情。

Google: 302 Redirect to Sign In Page Google: 302重定向到登录页面

请求 URL: https://mail.google.com/mail/u/0/?tab=cm请求方法: 状态代码: 302

回应: Content-type: text/html; charset = UTF-8 location: Https://accounts.google.com/servicelogin?service=mail&passive=1209600&osid=1&continue=https://mail.google.com/mail/u/0/?tab%3dcm&followup=https://mail.google.com/mail/u/0/?tab%3dcm&emr=1

Microsoft: 302重定向到登录页面

请求网址: Https://outlook.live.com/mail/0/?authredirect=true&state=0 方法: GET 状态代码: 302

回应: 地点: Https://outlook.live.com/owa/0/?state=1&redirectto=ahr0chm6ly9vdxrsb29rlmxpdmuuy29tl21hawwvmc8

Facebook: 302重定向到登录页面

请求 URL: https://www.facebook.com/friends请求方法: GET 状态代码: 302

回应: 地点: Https://www.facebook.com/login.php?next=https%3a%2f%2fwww.facebook.com%2ffriends

Twitter: 200,带有间歇登录页面

请求 URL: https://twitter.com/messages/请求方法: GET 状态 密码: 200(由服务人员发出)

我: 307: 临时重定向

我用这个超过十年了,从来没出过问题。不是建议其他人采用它,只是说它的工作原理就像每个主流浏览器宣传的302替代品一样。通过研究这个问题的答案,我可能会被说服转而使用302。

结论

302 是重定向的事实标准,除非您需要将一个 POST 重定向到另一个 POST,我没有尝试这样做。

实际上,我认为 POST 要么成功,要么彻底失败。POST 会导致服务器上的状态更改(例如将产品添加到库存中) ,并且您确实想知道更改是否被处理以及处理了多少次。重定向将引发在重定向之前是否接受更改的问题。一旦你决定永远不重定向一个 POST,那么302和307是等价的。302中的“ bug”是在不切实际的用例中出现的。因此,307不应该被创建。此外,302更受欢迎,因此可能是最好的支持。

对所有临时重定向使用单个代码的好处是,您不必担心重定向的原因。

200 与 JavaScript 抛出一个间歇登录页面是另一种选择,可能更适合单页面的网络应用程序。你要的页面,你拿到了,但是在你看到内容之前,你必须先登录。