在网页中,它使用 YUI 连接管理器/数据源向服务器发送 AJAX 请求,如果会话(包含有关用户是否已通过身份验证的信息)已经超时,那些只能通过身份验证查看的 ajax 响应用户应该返回一个http状态码,告诉客户端会话已经超时,然后客户端要么简单地将他重定向到登录页面,要么询问他是否要延长会话。
我的问题是,在这种情况下,什么 http 状态代码最适合告诉客户端会话已超时?
在网页中,它使用 YUI 连接管理器/数据源向服务器发送 AJAX 请求,如果会话(包含有关用户是否已通过身份验证的信息)已经超时,那些只能通过身份验证查看的 ajax 响应用户应该返回一个http状态码,告诉客户端会话已经超时,然后客户端要么简单地将他重定向到登录页面,要么询问他是否要延长会话。
我的问题是,在这种情况下,什么 http 状态代码最适合告诉客户端会话已超时?
我能建议的最好的是带有 WWW-Authenticate 标头的 HTTP 401 状态代码。
403请求的问题是RFC 2616声明“授权无济于事,请求不应重复”。(即,无论您是否经过身份验证,您永远都无法访问该资源)。
401请求的问题在于它声明它们“必须包含 WWW-Authenticate 标头字段”。正如有人指出的那样,在 WWW-Authenticate 标头中使用自定义值似乎并不违反规范。
我在RFC 2617中看不到任何原因,为什么 HTTP 401 状态与这样的自定义 WWW-Authenticate 标头相结合是不行的:
WWW-Authenticate: MyAuthScheme realm="http://example.com"
oAuth规范实际上似乎就是这样做的,因为他们建议这样做(尽管我认为他们对 RFC 有一个奇怪的解释):
WWW-Authenticate: OAuth realm="http://server.example.com/"
这似乎没有受到 RFC 的特别批准,但我实际上看不到它被它禁止(它似乎与任何必须或不得、应该或不应条件相冲突)。
我希望有一个更具体的 HTTP 状态代码用于超时和 CSRF 令牌无效等事情,这样就更清楚了。
我会推荐一个 HTTP 401。
403 基本上说,“你不被允许,走开,不要回来”,而 401 说,“我们不知道你是否被允许,因为你没有带上你的身份证。去吧得到它,然后再试一次。”
比较维基百科的定义:
HTTP 403 - 请求是合法请求,但服务器拒绝响应。
HTTP 401 - 类似于 403 Forbidden,但专门用于身份验证可能但失败或尚未提供的情况。
419 怎么样 - 它不是标准的,但Wikipedia 上的描述似乎适合:
419 认证超时
不是 HTTP 标准的一部分,419 Authentication Timeout 表示先前有效的身份验证已过期。它被用作 401 Unauthorized 的替代方案,以区别于其他经过身份验证的客户端被拒绝访问特定服务器资源的情况。
我相信适当的代码将是 403/Forbidden。没有任何与会话直接相关的内容。
根据Bobo 上面提供的Http Status Codes的 Wikipedia 链接:
440 Login Timeout (Microsoft)
A Microsoft extension. Indicates that your session has expired.
As you post a link, in that link i found this HTTP status code 440. you can use 440 HTTP status code for session expired.
440 Login Time-out
The client's session has expired and must log in again.
401 Unauthorized we can use when, user login credential is wrong. or auth token passed in header is invalid.
403 Forbidden we can use this when user does not has specific permission for requested resource.
So in my opinion we should use 440 Login Time-out.
事实是,会话超时没有标准的 HTTP 状态代码。会话是在应用层实现的,而不是 HTTP 传输层。
微软一直在为会话超时使用一个自定义状态代码:599,或者只是在 5xx 范围内组成您自己的状态代码。
来自状态代码 Wiki:
599 网络连接超时错误(未知) 此状态代码未在任何 RFC 中指定,但 Microsoft 公司使用 HTTP 代理向代理前面的客户端发送代理后面的网络连接超时信号。
我将自定义状态代码 599 用于会话超时,然后在 AJAX 响应中检查它。
从技术上讲,接受的答案当然是正确的:如果您已经确定您将失败的请求,并且您正在询问要返回哪个失败代码,那么 HTTP 401“未经授权(未经身份验证)”是合适的,以提示重新认证。
但首先,问问你自己:你应该让请求失败吗?
考虑到用户可能只是在访问您网站的公共页面,在这种情况下,您将用“未经授权!”打他们的脸。消息,并要求他们重新进行身份验证,以便查看他们通常无需身份验证即可看到的页面。这不酷。
我的建议是忽略会话令牌未知的事实,只需继续生成新会话令牌并为其创建新会话。会话的初始状态当然是“尚未验证”,因此如果用户尝试访问非公共页面,则该页面将确保他们收到 HTTP 401“未授权(未验证) "并且必须进行身份验证。但如果用户登陆公共页面,他们不会注意到任何不同。
我将使用 302 重定向响应,其中“Location”标头指向“/auth-required”之类的资源路径
客户端可以将资源路径路由到具有登录/密码表单的模式,避免将用户转移到另一个页面。
对于非 Ajax 请求,我使用 302 重定向。
对于 Ajax 请求,我使用 200 表示已知错误。这样我就可以利用数据对象。我发现数据对象比解析 jqXHR 信息更容易使用。然后我不需要担心尝试重新使用什么 HTTP 状态代码来适应我的情况。
jQuery 示例:
$.ajax({
//send data to server
})
.done(function(data, textStatus, jqXHR) {
if (data.success) {
//then process return data
}
else {
//get error type or message from data object
//could use custom error codes
}
})
.fail(function(jqXHR, textStatus, errorThrown) {
//handle unknown errors
});