应该使用什么http状态代码来告诉客户端会话已超时?


80

在一个网页中,它使用YUI连接管理器/数据源将AJAX请求发送到服务器,如果会话(其中包含有关用户是否已通过身份验证的信息)已经超时,则那些只能通过身份验证查看的ajax响应用户应返回一个http状态代码,告诉客户端会话已超时,然后客户端要么将其重定向到登录页面,要么询问他是否要扩展会话。

我的问题是,在这种情况下,哪种HTTP状态代码最适合告诉客户端会话已超时?

Wiki的HTTP状态代码列表


您是否要警告用户会话即将到期,以便用户可以执行一些更新操作?如果是这种情况,则必须由JavaScript中的计时器处理,该计时器在服务器上的会话超时之前关闭。到服务器发送状态代码时,它已经过期。如果您自动将它们重定向到另一个页面(如果它们使页面空闲),则还需要一个计时器。
杰森,

8
为什么,当然是418!矮胖……
Tim Post

Vaadin使用410 Gone,但是由于浏览器可以访问它,因此我不推荐使用
sreg

Answers:


65

我所能建议的最好是带有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似乎没有对此进行专门的保护,但是我实际上看不到它被它禁止(它似乎与任何“必须”,“不得”,“应该”或“不应”条件都没有冲突)。

我希望对于超时和CSRF令牌无效之类的问题,有一个更具体的HTTP状态代码,这样更清楚了。


34

我建议使用HTTP 401。

403基本上说:“您不允许,走开,再也不回来”,而401则说:“我们不知道是否允许您,因为您没有携带身份证。得到它,然后再试一次。”

比较Wikipedia的定义

HTTP 403-该请求是合法请求,但服务器拒绝响应。

HTTP 401-与403 Forbidden相似,但专门用于可以进行身份​​验证但已失败或尚未提供身份验证的情况。


3
401用于HTTP身份验证。RFC 2616说response MUST include a WWW-Authenticate header field。因此,在没有WWW-Authenticate标头字段的情况下发送该代码是错误的
toxalot

18

419怎么样-它不是标准的,但是Wikipedia上描述似乎合适:

419身份验证超时

419身份验证超时不是HTTP标准的一部分,它表示先前有效的身份验证已过期。它用作“ 401未经授权”的替代方法,以区别于被拒绝访问特定服务器资源的已通过身份验证的客户端。


14
知道这是哪里来的(维基百科除外)吗?如果它不在正式的RFC中,谁来定义它?
anaximander

5
它似乎也已从该Wiki页面中删除
Salem Ouerdani

这不是规范的一部分,HttpServletResponse如果您知道任何其他可靠的来源,最好参考Java @John。
Vishrant '18

我似乎只在PHP Laravel中使用
TroySteven

12

我相信适当的代码将是403 / Forbidden。没有与会话直接相关的任何会话。


1
绝对是正确的答案。由于会话已超时,因此该请求被禁止,因此这是最佳选择。
marcc

3
403告诉客户(基本上)“除非您修改请求,否则不要再这样做”,但是如果会话已建立,则不需要进行修改。此外,在大多数情况下,您无法对(当前)请求重新建立会话。
蒂姆·波斯特

1
究竟!我认为401会更好,但是它需要HTTP身份验证。我认为这要求沿着401 + 303(显然是704)的状态建立新的状态,这意味着“未经授权,请参阅其他以获得授权”。除了在语义上更加正确之外,它还可以是蹦床重定向的HTTP解决方案,基本上是“到这里,然后当您回来时,我们将再次尝试此操作”,这样登录页面就可以与目的地。
安东尼

5
我不同意这一点,RFC 2616明确声明了导致403响应“不得重复”的请求,以及“授权无济于事”的请求。
伊恩·柯林斯

5
authorization will not help-我认为这意味着HTTP身份验证无济于事。哪个是对的。发送授权标头将不会更改任何内容。401和403都不是理想的,但是我认为403比401更好。401会话超时是错误的,因为RFC 2616明确指出client MAY repeat the request with a suitable Authorization header field。但是,在这种情况下,客户端不应该重复请求(至少不是没有临时步骤)。不幸的是,我们无法将后半部分与状态代码进行通信。
toxalot

11

事实是,会话超时没有标准的HTTP状态代码。会话是在应用程序层而不是HTTP传输层中实现的。

Microsoft已经使用了一个自定义状态代码来进行会话超时:599,或者只是在5xx范围内组成您自己的状态代码。

从状态码Wiki:

599网络连接超时错误(未知)此状态代码未在任何RFC中指定,但是由Microsoft Corp.使用HTTP代理向代理前面的客户端发送信号,将代理后面的网络连接超时发出信号。

我将自定义状态代码599用于会话超时,然后在AJAX响应中进行检查。


3
网络连接超时与会话超时有很大不同。如果您要使用Microsoft扩展中的代码,为什么不440 Login Timeout (Microsoft)按照Faisal Mq的答案使用?
toxalot 2014年

那个有关599的维基百科页面是错误的,没有被引用。显然以前是说Microsoft代理在网络超时时提高了599,但是我也没有找到任何证据。
加雷斯·戴维森


8

当您发布链接时,在该链接中我找到了此HTTP状态代码440。您可以将440 HTTP状态代码用于会话过期。

440登录超时

 The client's session has expired and must log in again.

401未经授权,我们可以在用户登录凭据错误的情况下使用。或在标头中传递的身份验证令牌无效。

403禁止当用户对请求的资源没有特定权限时,可以使用此选项。

因此,我认为我们应该使用440 Login Time-out


2

从技术上讲,接受的答案当然是正确的:如果您已经确定将要失败该请求,并且正在询问要返回的失败代码,那么HTTP 401“未经授权(未经验证)”是合适的选择,以便提示重新认证。

但首先,问问自己: 您是否应该使请求失​​败?

考虑到用户可能只是访问您网站的公共页面,在这种情况下,您将用“未经授权!”将他们拍在脸上。消息,并要求他们重新进行身份验证,以查看通常无需身份验证即可看到的页面。那不酷。

我的建议是忽略会话令牌未知的事实,而只是继续生成一个新的会话令牌并为其创建一个新的会话。会话的初始状态当然将是“尚未认证”,因此,如果用户尝试访问非公共页面,则该页面将看到该页面,他们收到HTTP 401“未授权(未认证)” ”,并且必须进行身份验证。但是,如果用户登陆公共页面,他们将不会发现任何不同。


0

我将使用302重定向响应,其中“ Location”标头指向诸如“ / auth-required”之类的资源路径

客户端可以将资源路径路由到具有登录名/密码形式的模式,从而避免将用户转移到另一个页面。


-3

对于非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
});

6
不想解析响应不是偏离HTTP规范的充分理由,尤其是当您可以仅使用JSON.parse(responseText)时。
David Nelson

在这种情况下,我认为使用200响应代码不会偏离HTTP规范,因为该请求在传输层上在技术上是成功的。对我而言,会话超时类似于表单错误,在该表单错误中,我返回了用户友好的错误消息。在此问题的答案中表达的分歧清楚表明,HTTP规范提供行业认可的会话超时响应代码。如何偏离不存在的规范?
toxalot

-4

代码408。“请求超时”似乎很完美-RFC 2616解释了它的意思

客户端在服务器准备等待的时间内未产生请求。

即,正是您所需要的“超时”!


4
嗯,但是请看一下其余的定义:“客户端可以在以后的任何时间重复请求而无需进行修改。” “未经修改”将意味着只需重新加载/刷新请求即可创建新会话。在大多数情况下,使用身份验证时,用户将必须先重新登录。
AJ。

@AJ,当然,重复的请求可能会遇到身份验证挑战(HTTP代码401)-在HTTP规范中看不到任何禁止的内容,您可以指向任何内容吗?
Alex Martelli,2009年

5
408告诉客户端,他们应该尝试按原样重新提交请求,如果会话超时,显然这是行不通的。
蒂姆·波斯特

4
408是“请求”超时,而不是会话超时。意思是,套接字已建立,但用时太长。这个网站做了很好的解释:checkupdown.com/status/E408.html
Brad Cupit 2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.