Mã trạng thái http nào được sử dụng để cho khách hàng biết phiên đã hết thời gian?


80

Trong một trang web, nó sử dụng trình quản lý kết nối YUI / nguồn dữ liệu để gửi các yêu cầu AJAX đến máy chủ, nếu phiên (chứa thông tin về việc người dùng đã được xác thực hay chưa) đã hết thời gian chờ, thì những phản hồi ajax đó chỉ có thể được xem bằng cách xác thực người dùng phải trả lại mã trạng thái http, thông báo cho khách hàng rằng phiên đã hết thời gian chờ, sau đó khách hàng chỉ cần chuyển hướng anh ta đến trang đăng nhập hoặc hỏi anh ta có muốn kéo dài phiên hay không.

Câu hỏi của tôi là, trong tình huống này, mã trạng thái http nào là thích hợp nhất để cho khách hàng biết phiên đã hết thời gian chờ?

Danh sách mã trạng thái HTTP từ wiki


Bạn có muốn cảnh báo người dùng rằng phiên sắp hết hạn để người dùng có thể làm gì đó để gia hạn không? Nếu đúng như vậy, nó sẽ phải được xử lý bởi một bộ đếm thời gian trong JavaScript hoạt động trước khi hết thời gian phiên trên máy chủ. Vào thời điểm mã trạng thái được gửi bởi máy chủ, nó đã hết hạn. Cũng sẽ cần một bộ hẹn giờ nếu bạn đang tự động chuyển hướng họ đến một trang khác nếu họ để trang không hoạt động.
Jason

8
Tại sao, tất nhiên là 418! Ngắn và mập mạp ...
Tim Post

Vaadin sử dụng 410 Gone, nhưng vì nó có thể được trình duyệt truy cập, tôi không khuyên bạn nên sử dụng nó
sreg

Câu trả lời:


66

Tốt nhất tôi có thể đề xuất là mã trạng thái HTTP 401 với tiêu đề WWW-Authenticate.

Vấn đề với các yêu cầu 403RFC 2616 nêu rõ "Việc cấp phép sẽ không giúp ích được gì và yêu cầu KHÔNG NÊN được lặp lại." (tức là không quan trọng nếu bạn được xác thực hay không, bạn sẽ không bao giờ có quyền truy cập vào tài nguyên đó).

Vấn đề với các yêu cầu 401 là nó nói rằng chúng "PHẢI bao gồm trường tiêu đề WWW-Authenticate". Như ai đó đã lưu ý, dường như không vi phạm thông số kỹ thuật để sử dụng giá trị tùy chỉnh trong tiêu đề WWW-Authenticate.

Tôi không thể thấy bất kỳ lý do nào trong RFC 2617 tại sao trạng thái HTTP 401 kết hợp với tiêu đề WWW-Authenticate tùy chỉnh như thế này sẽ không ổn:

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

Thông số oAuth thực sự dường như chỉ làm điều này, vì họ đề xuất điều này (mặc dù tôi nghĩ rằng họ phải hiểu một cách kỳ quặc về RFC):

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

Điều này dường như không bị RFC XỬ PHẠT cụ thể, nhưng tôi thực sự không thể thấy rằng nó bị cấm (nó dường như không mâu thuẫn với bất kỳ điều kiện PHẢI hoặc KHÔNG PHẢI, NÊN hoặc KHÔNG NÊN).

Tôi ước có một mã trạng thái HTTP cụ thể hơn cho thời gian chờ và những thứ như mã thông báo CSRF không hợp lệ để điều này rõ ràng hơn.


34

Tôi muốn giới thiệu một HTTP 401.

Trong khi 403 về cơ bản nói, "Bạn không được phép, hãy biến đi và đừng quay lại", thì 401 nói, "Chúng tôi không biết liệu bạn có được phép hay không vì bạn không mang theo giấy tờ tùy thân. Đi lấy nó và thử lại. "

So sánh các định nghĩa của Wikipedia :

HTTP 403 - Yêu cầu là một yêu cầu hợp pháp nhưng máy chủ từ chối phản hồi.

HTTP 401 - Tương tự như 403 Forbidden, nhưng đặc biệt để sử dụng khi có thể xác thực nhưng không thành công hoặc chưa được cung cấp.


3
401 có nghĩa là để xác thực HTTP . RFC 2616 nói response MUST include a WWW-Authenticate header field. Vì vậy, thật sai lầm khi gửi mã đó mà không có trường tiêu đề WWW-Authenticate .
toxalot

19

Còn 419 thì sao - nó không chuẩn, nhưng mô tả trên Wikipedia có vẻ phù hợp:

419 Thời gian chờ xác thực

Không phải là một phần của tiêu chuẩn HTTP, 419 Authentication Timeout biểu thị rằng xác thực hợp lệ trước đó đã hết hạn. Nó được sử dụng như một giải pháp thay thế cho 401 Unauthorized để phân biệt với các máy khách được xác thực khác đang bị từ chối truy cập vào các tài nguyên máy chủ cụ thể.


14
Bất kỳ ý tưởng nào điều này đến từ đâu (ngoài Wikipedia)? Nếu nó không có trong RFC chính thức, ai đã định nghĩa nó?
anaximander

5
Nó có vẻ cũng được gỡ bỏ từ đó trang wiki
Salem Ouerdani

Đây không phải là một phần của đặc điểm kỹ thuật, không có sẵn trong Java HttpServletResponse@John nếu bạn biết bất kỳ nguồn đáng tin cậy nào khác, tốt hơn là bạn nên tham khảo nó.
Vishrant

Tôi dường như chỉ được sử dụng trong PHP Laravel
TroySteven

12

Tôi tin rằng mã thích hợp sẽ là 403 / Forbidden. Không có bất kỳ liên quan trực tiếp đến phiên.


1
Hoàn toàn đây là câu trả lời chính xác. Vì phiên đã hết thời gian, yêu cầu bị cấm, vì vậy đây là lựa chọn tốt nhất.
marcc,

3
403 nói với khách hàng (về cơ bản) "Đừng làm điều đó lần nữa trừ khi bạn sửa đổi yêu cầu của mình", nhưng nếu phiên đã được thiết lập, sẽ không cần sửa đổi. Hơn nữa, bạn không thể làm bất kỳ điều gì với yêu cầu (hiện tại) để thiết lập lại phiên trong hầu hết các trường hợp.
Tim Post

1
Chính xác! Tôi nghĩ 401 sẽ tốt hơn, nhưng nó yêu cầu xác thực HTTP. Tôi nghĩ rằng điều này yêu cầu một trạng thái mới dọc theo dòng 401 + 303 (vì vậy, rõ ràng, 704) có nghĩa là "Không được ủy quyền, Hãy xem phần khác để nhận được ủy quyền". Ngoài việc nó chính xác hơn về mặt ngữ nghĩa, nó cũng có thể là giải pháp HTTP để chuyển hướng tấm bạt lò xo, về cơ bản là "hãy truy cập vào đây, sau đó khi bạn quay lại, chúng tôi sẽ thử lại điều này", vì vậy trang đăng nhập có thể không liên quan đến Nơi Đến.
Anthony

5
Tôi không thể đồng ý với điều này, RFC 2616 tuyên bố rõ ràng rằng các yêu cầu dẫn đến phản hồi 403 "KHÔNG NÊN lặp lại" bởi ứng dụng khách và "ủy quyền sẽ không hữu ích".
Iain Collins

5
authorization will not help- Tôi hiểu điều đó có nghĩa là xác thực HTTP sẽ không giúp ích gì. Cái nào đúng. Việc gửi tiêu đề Ủy quyền sẽ không thay đổi bất kỳ điều gì. Cả 401 và 403 đều không phải là lý tưởng, nhưng tôi nghĩ rằng 403 tốt hơn 401. 401 là sai cho thời gian chờ phiên vì RFC 2616 nêu rõ ràng client MAY repeat the request with a suitable Authorization header field. Tuy nhiên, trong trường hợp này, khách hàng KHÔNG NÊN lặp lại yêu cầu (ít nhất là không có bước tạm thời). Rất tiếc, chúng tôi không thể giao tiếp phần sau bằng mã trạng thái.
toxalot

11

Sự thật là không có mã trạng thái HTTP tiêu chuẩn cho thời gian chờ của phiên. Các phiên được triển khai trong lớp ứng dụng, không phải lớp truyền tải HTTP.

Có một mã trạng thái tùy chỉnh mà Microsoft đã sử dụng cho thời gian chờ phiên: 599, hoặc chỉ cần tạo mã trạng thái của riêng bạn trong phạm vi 5xx.

Từ Wiki Mã Trạng thái:

599 Lỗi hết thời gian chờ kết nối mạng (Không xác định) Mã trạng thái này không được chỉ định trong bất kỳ RFC nào, nhưng được sử dụng bởi proxy HTTP của Microsoft Corp. để báo hiệu thời gian chờ kết nối mạng phía sau proxy tới một ứng dụng khách phía trước proxy.

Tôi sử dụng mã trạng thái tùy chỉnh 599 cho thời gian chờ của phiên và sau đó kiểm tra nó trong phản hồi AJAX.


3
Thời gian chờ kết nối mạng rất khác với thời gian chờ phiên. Nếu bạn đang sử dụng một mã từ một phần mở rộng của Microsoft, tại sao không sử dụng 440 Login Timeout (Microsoft)theo câu trả lời Faisal MQ của
toxalot

Trang Wikipedia về 599 đó đã sai và không có trích dẫn nào. Dường như đã từng nói rằng proxy của Microsoft tăng 599 khi mạng hết thời gian chờ, nhưng tôi cũng không thể tìm thấy bất kỳ bằng chứng nào về điều đó.
Gareth Davidson


9

Khi bạn đăng một liên kết, trong liên kết đó, tôi đã tìm thấy mã trạng thái HTTP 440 này . bạn có thể sử dụng mã trạng thái 440 HTTP cho phiên hết hạn.

440 Thời gian chờ đăng nhập

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

401 Chúng tôi có thể sử dụng trái phép khi, thông tin đăng nhập của người dùng bị sai. hoặc mã thông báo xác thực được chuyển vào tiêu đề không hợp lệ.

403 Forbidden, chúng tôi có thể sử dụng điều này khi người dùng không có quyền cụ thể đối với tài nguyên được yêu cầu.

Vì vậy, theo tôi chúng ta nên sử dụng 440 Thời gian chờ đăng nhập .


2

Về mặt kỹ thuật, câu trả lời được chấp nhận tất nhiên là đúng: Nếu bạn đã biết chắc chắn rằng mình sẽ không thực hiện yêu cầu và bạn đang hỏi mã lỗi nào sẽ trả về, thì HTTP 401 "Unauthorized (Unauthenticated)" là câu trả lời thích hợp, để nhanh chóng xác thực lại.

Nhưng trước hết, hãy tự hỏi bản thân: bạn có nên thất bại yêu cầu không?

Hãy xem xét rằng người dùng có thể chỉ đơn giản là đang truy cập một trang công khai trên trang web của bạn, trong trường hợp đó, bạn sẽ tát thẳng vào mặt họ với câu "Không được phép!" và yêu cầu họ xác thực lại để xem trang mà họ thường có thể xem mà không cần xác thực. Không hay đâu.

Lời khuyên của tôi là bỏ qua thực tế rằng mã thông báo phiên không xác định và chỉ cần tiến hành tạo mã thông báo phiên mới và tạo phiên mới cho nó. Trạng thái ban đầu của phiên tất nhiên sẽ là "chưa được xác thực", vì vậy nếu người dùng đang cố truy cập một trang không công khai, thì trang đó sẽ thấy rằng họ nhận được HTTP 401 "Unauthorized (Chưa được xác thực) ”và phải xác thực. Nhưng nếu người dùng truy cập vào một trang công khai, họ sẽ không nhận thấy bất kỳ điều gì khác biệt.


0

Tôi sẽ sử dụng phản hồi chuyển hướng 302, với tiêu đề "Vị trí" hướng đến đường dẫn tài nguyên như "/ auth-Required"

Máy khách có thể định tuyến đường dẫn tài nguyên đến một phương thức với biểu mẫu đăng nhập / mật khẩu, tránh chuyển người dùng sang trang khác.


-3

Đối với các yêu cầu không phải Ajax, tôi sử dụng chuyển hướng 302.

Đối với các yêu cầu Ajax, tôi sử dụng 200 cho các lỗi đã biết . Bằng cách đó tôi có thể tận dụng lợi thế của đối tượng dữ liệu. Tôi thấy đối tượng dữ liệu dễ làm việc hơn là phân tích cú pháp jqXHR để biết thông tin. Và sau đó tôi không cần phải lo lắng về mã trạng thái HTTP nào để cố gắng sử dụng lại mục đích cho tình huống của mình.

Ví dụ 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
Không muốn phân tích cú pháp phản hồi không phải là lý do chính đáng để đi chệch khỏi thông số HTTP, đặc biệt khi bạn chỉ có thể JSON.parse (responseText).
David Nelson

Tôi không nghĩ rằng việc sử dụng mã phản hồi 200 sai lệch so với thông số HTTP trong trường hợp này vì yêu cầu đã thành công về mặt kỹ thuật ở lớp truyền tải. Đối với tôi, thời gian chờ của phiên tương tự như lỗi biểu mẫu trong đó tôi trả về thông báo lỗi thân thiện với người dùng. Những bất đồng được thể hiện trong các câu trả lời cho câu hỏi này chỉ ra rõ ràng rằng thông số HTTP không cung cấp mã phản hồi được ngành chấp nhận cho thời gian chờ của phiên. Làm thế nào một người có thể đi chệch khỏi một thông số kỹ thuật không tồn tại?
toxalot

-4

Mã 408. "Yêu cầu hết thời gian chờ", có vẻ hoàn hảo - RFC 2616 giải thích điều đó có nghĩa là

Máy khách không đưa ra yêu cầu trong thời gian máy chủ chuẩn bị đợi.

tức là, chính xác là một "time-out", như bạn yêu cầu!


4
À, nhưng hãy xem phần còn lại của định nghĩa: "Khách hàng có thể lặp lại yêu cầu mà không cần sửa đổi bất kỳ lúc nào sau này." "Không có sửa đổi" sẽ ngụ ý rằng một phiên mới có thể được tạo đơn giản bằng cách tải lại / làm mới yêu cầu. Trong hầu hết các trường hợp, khi xác thực đang được sử dụng, người dùng sẽ phải đăng nhập lại trước.
AJ.

@AJ, tất nhiên yêu cầu lặp lại có thể gặp phải thử thách xác thực (mã HTTP 401) - không thấy bất kỳ điều gì trong thông số kỹ thuật HTTP cấm điều đó , bạn có thể chỉ vào bất cứ điều gì không?
Alex Martelli,

5
408 nói với khách hàng rằng họ chỉ nên thử gửi lại yêu cầu như cũ, điều này rõ ràng là không thể hoạt động nếu phiên đã hết thời gian.
Tim Post

4
408 là thời gian chờ 'yêu cầu' không phải thời gian chờ của phiên. Có nghĩa là, ổ cắm đã được thành lập nhưng mất quá nhiều thời gian. Trang web này hiện tốt công việc giải thích nó: checkupdown.com/status/E408.html
Brad Cupit
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.