2009-10-31 166 views
60

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

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

List of HTTP status codes from wiki

+0

您是否想警告用户会话即将过期,以便用户可以做些更新操作?如果是这样的话,它必须由JavaScript中的计时器处理,该计时器在服务器上的会话超时之前关闭。当服务器发送状态码时,它已经过期。如果您在页面闲置时将自动重定向到另一个页面,则还需要定时器。 – Jason 2009-10-31 05:45:49

+6

为什么,当然是418! Short and stout ... – 2009-10-31 05:47:59

+0

Vaadin使用410 Gone,但由于它可以被浏览器缓存,所以我不会推荐它 – sreg 2015-08-14 15:48:33

回答

52

我可以建议的最好是带有WWW-Authenticate标头的HTTP 401状态码。

问题请求是RFC 2616状态“授权不起作用,请求不应该重复。” (即,如果您通过了身份验证,则无关紧要,您将永远无法访问该资源)。

这个问题表明它们“必须包含一个WWW-Authenticate头域”。由于someone has noted它似乎没有违反规范在WWW-Authenticate标头中使用自定义值。

我看不到任何RFC 2617之所以一个HTTP 401状态用一个自定义的WWW-Authenticate头相结合这样就不会好起来的:

WWW-Authenticate: MyAuthScheme realm="http://example.com" 

oAuth spec实际上似乎只是该做的,他们建议这(虽然他们使我想起了RFC的奇解释):

WWW-Authenticate: OAuth realm="http://server.example.com/" 

这似乎并非由RFC具体制裁,但我不能真正看到它通过禁止它(它似乎没有冲突机智h任何必须或不能,应该或不应该条件)。

我希望有一个更具体的HTTP状态码超时和像CSRF令牌的东西无效,所以这是更清晰的。

-2

代码408“请求超时”,似乎是完美的 - RFC 2616解释这意味着

客户端并没有产生的时间内请求 服务器是 准备等待。

即准确地说“超时”,就像你需要!

+3

啊,但看看其余的定义: “客户端可能会重复请求而不做修改在任何晚些时候。“ “没有修改”意味着只需重新加载/刷新请求即可创建新会话。在大多数情况下,当使用身份验证时,用户必须先重新登录。 – 2009-10-31 05:33:09

+0

@AJ,当然重复的请求可能会遇到认证质询(HTTP代码401) - 在HTTP规范中没有看到禁止**的任何内容**,您可以指向任何内容吗? – 2009-10-31 05:43:16

+4

408告诉客户他们应该尝试重新提交请求,如果会话超时,这显然不能工作。 – 2009-10-31 11:37:58

13

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

+0

绝对这是正确的答案。由于会话超时,请求被禁止,所以这是最好的选择。 – marcc 2009-10-31 05:37:48

+3

403告诉客户(基本上)“除非您修改您的请求,否则不要再这样做”,但如果会话已建立,则不需要进行修改。此外,在大多数情况下,您无法对(当前)请求重新建立会话做任何事情。 – 2009-10-31 11:37:00

+1

准确!我认为401会更好,但它需要HTTP认证。我认为这需要401 + 303的新的地位(显然,704),这意味着“没有授权,请参见其他获得授权”。除了它在语义上更加正确之外,它也可以是蹦床重定向的HTTP解决方案,基本上是“去这里,然后当你回来时我们会再试一次”,这样登录页面可以是不可知的目的地。 – Anthony 2012-04-01 12:08:11

25

我会建议一个HTTP 401

而一个403基本上说,“你不允许的,走不回来”,401说,“我们不知道,如果你'是否允许,因为你没有带上你的身份证,去得到它,然后再试一次。“

比较Wikipedia's definitions

HTTP 403 - 请求是合法的请求,但服务器拒绝对此作出回应。

HTTP 401 - 类似于403 Forbidden,但专门用于认证可能但尚未提供或尚未提供的情况。

+3

401旨在用于* HTTP身份验证*。 RFC 2616指出“响应必须包含一个WWW-Authenticate头域”。所以它*错*发送没有* WWW-Authenticate头字段*的代码。 – toxalot 2014-03-18 20:01:48

10

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

Microsoft有一个自定义状态代码,用于会话超时:599,或者只是在5xx范围内构建自己的状态代码。

从状态代码维基:

599网络连接超时错误(未知) 此状态码不以任何RFC中指定,而是使用由微软公司HTTP代理发信号通知网络连接超时背后的代理前的客户端。

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

+3

网络连接超时与会话超时非常不同。如果您打算使用Microsoft扩展的代码,那么为什么不按照[Faisal Mq的答案](http://stackoverflow.com/a/22484262/1862009) – toxalot 2014-03-18 19:54:41

+0

使用'440登录超时(Microsoft)'Wikipedia页面约599是错误的,没有引用。它显然曾经说过,微软代理在网络超时时间上提高了599,但我也找不到任何证据。 – 2017-08-03 10:41:32

-2

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

不想分析响应不是一个偏离HTTP规范的好理由,特别是当你只能使用JSON.parse(responseText)时。 – 2014-04-17 15:02:22

16

什么419 - 它不是标准,而是description on Wikipedia似乎适合:

419验证超时

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

+11

任何想法来自哪里(维基百科除外)?如果它不在官方的RFC中,谁定义了它? – anaximander 2013-08-16 10:32:17

+3

它似乎也从该wiki页面中删除 – 2016-04-23 13:45:15

+0

这不是规范的一部分,在Java'HttpServletResponse' @John中都不可用,如果您知道任何其他可靠的源代码可以更好地引用它。 – Vishrant 2018-02-17 07:41:47

8

按照由波波上面提供的Http Status Codes维基百科的链接:

440 Login Timeout (Microsoft) 

    A Microsoft extension. Indicates that your session has expired. 
+0

注意apache可能会将返回状态转换为500,就像我的做法一样 - https://stackoverflow.com/questions/17735514/php-apache-silently-converting-http-429-and-others-to-500 – commonpike 2018-01-28 10:43:53

0

技术上,公认的答案是正确的:如果你已经确切知道你将要失败的请求,并且您询问要返回哪个失败代码,则HTTP 401“未经授权(Unauthenticated)”是适当的,以便提示重新进行身份验证。

但首先,问自己:你应该请求失败?

想象一下,用户可能只是访问您的网站的公共页面,在这种情况下,您会用“未经授权的!消息,并要求他们重新进行身份验证,以便查看他们通常无需身份验证就能看到的页面。这并不酷。

我的建议是忽略的事实是会话令牌是未知的,只是继续生成令牌一个新的会话,并为它创建一个新的会话。会话的初始状态当然是“尚未认证”的,所以如果用户试图访问非公开页面,那么页面会看到他们收到HTTP 401“Unauthorized(Unauthenticated)”, “并且必须认证。但是,如果用户登录公共页面,他们将不会注意到任何不同。