应该用什么 HTTP状态码来告诉客户会话已超时?

在一个网页中,它使用 YUI 连接管理器/数据源向服务器发送 AJAX 请求,如果会话(其中包含用户是否已经验证)已经超时,那些只能被验证用户查看的 AJAX 响应应该返回一个 HTTP状态码,告诉客户会话已经超时,然后客户端要么简单地重定向到登录页面,要么问他是否想要扩展会话。

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

来自 wiki 的 HTTP 状态代码列表

84132 次浏览

Code 408. "Request timeout", seems perfect -- RFC 2616 explains it means

The client did not produce a request within the time that the server was prepared to wait.

i.e., exactly a "time-out", just as you require!

I believe the appropriate code is going to be 403/Forbidden. There aren't any that are directly related to sessions.

I would recommend an HTTP 401.

Whereas a 403 basically says, "You're not allowed, go away and don't come back", a 401 says, "We don't know if you're allowed or not because you didn't bring your ID. Go get it and try again."

Compare Wikipedia's definitions:

HTTP 403 - The request was a legal request, but the server is refusing to respond to it.

HTTP 401 - Similar to 403 Forbidden, but specifically for use when authentication is possible but has failed or not yet been provided.

Best I can suggest is a HTTP 401 status code with a WWW-Authenticate header.

The problem with 403 requests is the the RFC 2616 states "Authorization will not help and the request SHOULD NOT be repeated." (i.e. doesn't matter if you are authenticated or not, you are not going to get access to that resource, ever).

The problem with 401 requests is it states they "MUST include a WWW-Authenticate header field". As someone has noted it doesn't appear to be in violation of the spec to use a custom value in a WWW-Authenticate header.

I can't see any reason in RFC 2617 why an HTTP 401 status combined with a custom WWW-Authenticate header like this wouldn't be okay:

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

The oAuth spec actually seems to do just this, as they recommend this (though they have to my mind an odd interpretation of the RFC):

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

This doesn't appear to be specifically SANCTIONED by the RFC, but I can't actually see that it's forbidden by it (it doesn't seem to conflict with any MUST or MUST NOT, SHOULD or SHOULD NOT condition).

I wish there was a more specific HTTP status code for timeouts and for things like CSRF tokens being invalid so this was clearer.

Truth is, there is no standard HTTP status code for a session timeout. Sessions are implemented in the application layer, not the HTTP transport layer.

There is a custom status code that Microsoft have been using for session timeout: 599, or simply make up your own status code in the 5xx range.

From the Status Codes Wiki:

599 Network connect timeout error (Unknown) This status code is not specified in any RFCs, but is used by Microsoft Corp. HTTP proxies to signal a network connect timeout behind the proxy to a client in front of the proxy.

I use the custom status code 599 for a session timeout and then check for it in the AJAX response.

For non-Ajax requests, I use a 302 redirect.

For Ajax requests, I use 200 for known errors. That way I can take advantage of the data object. I find the data object easier to work with than parsing jqXHR for info. And then I don't need to worry about what HTTP status code to try to re-purpose for my situation.

jQuery Example:

$.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
});

What about 419 - it is not standard, but the description on Wikipedia seems to fit:

419 Authentication Timeout

Not a part of the HTTP standard, 419 Authentication Timeout denotes that previously valid authentication has expired. It is used as an alternative to 401 Unauthorized in order to differentiate from otherwise authenticated clients being denied access to specific server resources.

As per the Wikipedia link of Http Status Codes provided above by Bobo:

440 Login Timeout (Microsoft)


A Microsoft extension. Indicates that your session has expired.

Technically, the accepted answer is of course correct: If you already know for sure that you are going to be failing the request, and you are asking which failure code to return, then HTTP 401 "Unauthorized (Unauthenticated)" is the appropriate one, so as to prompt re-authentication.

But first of all, ask yourself: should you fail the request?

Consider that the user may simply be visiting a public page of your website, in which case you are going to be slapping them across the face with an "Unauthorized!" message, and requiring them to re-authenticate, in order to see a page that they would normally be able to see without authentication. That's not cool.

My advice is to ignore the fact that the session token is unknown, and simply proceed to generate a new session token and create a new session for it. The initial state of the session will of course be "not-yet-authenticated", so if the user is trying to access a non-public page, then the page will see to it that they receive an HTTP 401 "Unauthorized (Unauthenticated)" and must authenticate. But if the user lands on a public page, they won't notice anything different.

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 : Microsoft's Internet Information Services (IIS)

 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 you can use one of the above statusCode.

I would use a 302 redirection response, with a "Location" header directing to a resource path like "/auth-required"

The client could route the resource path to a modal with a login/password form, avoiding to tranfer the user to another page.