首页 文章

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

提问于
浏览
107

当用户未登录并尝试访问需要登录的页面时,重定向到登录页面的正确HTTP状态代码是什么?

我问,因为3xx response codes set out by the W3C似乎都不符合要求:

10.3.1 300多个选择所请求的资源对应于一组表示中的任何一个,每个表示都有自己的特定位置,并且正在提供代理驱动的协商信息(第12节),以便用户(或用户代理)可以选择首选表示并将其请求重定向到该位置 . 除非是HEAD请求,否则响应应该包括一个实体,其中包含资源特征和位置列表,用户或用户代理可以从中选择最合适的资源特征和位置 . 实体格式由Content-Type头字段中给出的媒体类型指定 . 根据用户代理的格式和功能,可以自动选择最合适的选择 . 但是,该规范没有为这种自动选择定义任何标准 . 如果服务器具有首选的表示选择,则它应该在Location字段中包含该表示的特定URI;用户代理可以使用Location字段值进行自动重定向 . 除非另有说明,否则该响应是可缓存的 . 10.3.2 301永久移动已为所请求的资源分配了一个新的永久URI,以后对该资源的任何引用应该使用返回的URI之一 . 具有链接编辑功能的客户端应尽可能自动将对Request-URI的引用重新链接到服务器返回的一个或多个新引用 . 除非另有说明,否则该响应是可缓存的 . 新的永久URI应该由响应中的Location字段给出 . 除非请求方法是HEAD,否则响应的实体应该包含一个带有指向新URI的超链接的短超文本注释 . 如果收到301状态代码以响应GET或HEAD以外的请求,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件 . 注意:在自动重定向POST请求之后
接收301状态代码,一些现有的HTTP / 1.0用户代理
将错误地将其更改为GET请求 .
10.3.3 302 Found找到的资源暂时驻留在不同的URI下 . 由于重定向有时可能会被更改,因此客户端应该继续使用Request-URI来处理将来的请求 . 如果由Cache-Control或Expires头字段指示,则此响应仅可缓存 . 临时URI应该由响应中的Location字段给出 . 除非请求方法是HEAD,否则响应的实体应该包含一个带有指向新URI的超链接的短超文本注释 . 如果收到302状态代码以响应GET或HEAD以外的请求,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件 . 注意:RFC 1945和RFC 2068指定不允许客户端
更改重定向请求的方法 . 但是,大多数
现有的用户代理实现将302视为就像它一样
是一个303响应,无论原始请求方法如何,都在Location字段值上执行GET . 已经为希望明确清楚客户端期望哪种反应的服务器添加了状态代码303和307 . 10.3.4 303见其他对请求的响应可以在不同的URI下找到,并且应该使用该资源上的GET方法检索 . 此方法主要用于允许输出POST激活的脚本以将用户代理重定向到选定的资源 . 新URI不是最初请求的资源的替代引用 . 303响应绝不能被缓存,但对第二个(重定向)请求的响应可能是可缓存的 . 不同的URI应该由响应中的Location字段给出 . 除非请求方法是HEAD,否则响应的实体应该包含一个带有指向新URI的超链接的短超文本注释 . 注意:许多pre-HTTP / 1.1用户代理不理解303
状态 . 当与这些客户端的互操作性成为一个问题时,
因为大多数用户代理会做出反应,所以可以使用302状态代码
如此处针对303描述的302响应 .
10.3.5 304未修改如果客户端已执行条件GET请求并允许访问,但文档尚未修改,则服务器应该响应此状态代码 . 304响应必须不包含消息体,因此总是在头字段之后的第一个空行终止 . 响应必须包括以下 Headers 字段: - 日期,除非需要省略第14.18.1节如果a
无时钟源服务器服从这些规则,代理和客户端将自己的日期添加到任何没有响应的响应中(如[RFC 2068]第14.19节所述),高速缓存将正常运行 . - ETag和/或Content-Location,如果 Headers 已被发送
在对同一请求的200响应中

  • 如果字段值可能,则为Expires,Cache-Control和/或Vary
    与之前任何响应中发送的内容不同
    变量如果条件GET使用了强缓存验证器(请参阅
    第13.3.3节),响应不应包括其他实体 Headers . 否则(即,条件GET使用弱验证器),响应绝不能包括其他实体头;这可以防止缓存的实体主体和更新的标头之间的不一致 . 如果304响应指示当前未缓存的实体,则缓存必须忽略响应并在没有条件的情况下重复请求 . 如果高速缓存使用接收的304响应来更新高速缓存条目,则高速缓存必须更新该条目以反映响应中给出的任何新字段值 . 10.3.6 305使用代理必须通过Location字段给出的代理访问所请求的资源 . Location字段提供代理的URI . 预计收件人将通过代理重复此单个请求 . 305响应必须只由原始服务器生成 . 注意:RFC 2068并不清楚305是否意图重定向a
    单个请求,仅由原始服务器生成 . 不
    观察这些限制会产生重大的安全后果 .
    10.3.7 306(未使用)306状态代码用于规范的先前版本,不再使用,代码保留 . 10.3.8 307临时重定向请求的资源临时驻留在不同的URI下 . 由于重定向有时可能会被更改,因此客户端应该继续使用Request-URI来处理将来的请求 . 如果由Cache-Control或Expires头字段指示,则此响应仅可缓存 . 临时URI应该由响应中的Location字段给出 . 除非请求方法是HEAD,否则响应的实体应该包含一个带有指向新URI的超链接的短超文本注释,因为许多HTTP / 1.1前用户代理不理解307状态 . 因此,注释应该包含用户在新URI上重复原始请求所需的信息 . 如果收到307状态代码以响应GET或HEAD以外的请求,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件 .

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

Update & conclusion:

HTTP 302更好,因为它已知与客户端/浏览器具有最佳兼容性 .

4 回答

  • 51

    我会说303见其他 302 Found:

    请求的资源暂时驻留在不同的URI下 . 由于重定向有时可能会被更改,因此客户端应该继续使用Request-URI来处理将来的请求 . 如果由Cache-Control或Expires头字段指示,则此响应仅可缓存 .

    在我看来,最贴近登录页面 . 我最初认为 303 see other 也可以 . 经过一番思考后,我会说 302 Found 更合适,因为找到了所请求的资源,在访问它之前只有另一个页面要经过 . 默认情况下,响应不会被缓存,这也很好 .

  • -1

    这是对HTTP重定向机制的误用 . 如果用户未获得授权,则您的应用必须返回 401 Unauthorized . 如果用户已获得授权但无法访问所请求的资源,则必须返回 403 Forbidden .

    您应该在客户端进行重定向,例如通过javascript . status code for redirection because required authorization does not exist . 为此使用30x不符合HTTP .

    How to Think About HTTP Status Codes by Mark Nottingham

    401 Unauthorized触发HTTP的请求认证机制 .

    401 Unauthorized 状态代码需要存在支持各种身份验证类型的 WWW-Authenticate 标头:

    WWW-Authenticate:<type> realm = <realm>

    持票人,OAuth,基本,摘要,Cookie等

  • 11

    我认为适当的解决方案是HTTP 401(未授权)标头 .

    http://en.wikipedia.org/wiki/HTTP_codes#4xx_Client_Error

    这个 Headers 的目的就是这个 . 但是,不是重定向到登录页面,而是正确的过程如下:

    • 未登录用户尝试访问登录受限页面 .

    • system标识用户未记录

    • 系统返回HTTP 401标头,并在同一响应中显示登录表单(不是重定向) .

    这是一个很好的做法,例如提供有用的404页面,站点 Map 链接和搜索表单 .

    再见 .

  • 42

    我很少见Firefox浏览器缓存302重定向 . 这就是我使用307登录页面的原因,例如重定向到最新文章/帖子/评论/等 .

    如果您使用302,请不要忘记仔细检查缓存是否正常禁用:

    header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
    header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
    header('Cache-Control: no-cache');
    header('Pragma: no-cache');
    header('Cache-Control: post-check=0, pre-check=0', false);
    

相关问题