Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to send a 401 Unauthorized AND redirect (with a Location)?

I'd like to send a 401 Unauthorized AND redirect the client somewhere. However:

if I do it like this:

header('HTTP/1.1 401 Unauthorized');
header('Location: /');

the server sends a 302 Found with Location, so not a 401 Unauthorized.

If I do it like this:

header('Location: /');
header('HTTP/1.1 401 Unauthorized');

the browser receives both a 401 Unauthorized and a Location, but does not redirect.

(IE 9 and Chrome 16 behave the same, so I'm guessing it's correct)

Maybe I'm misusing HTTP? I'd like my app interface to be exactly the same for all clients: text browser, modern browser, API calls etc. The 401 + response text would tell an API user what's what. The redirect is useful for a browser.

Is there a (good) way?

like image 655
Rudie Avatar asked Jan 08 '12 05:01

Rudie


People also ask

What is a 401 redirect?

The HyperText Transfer Protocol (HTTP) 401 Unauthorized response status code indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.

What could be the possible reasons for 401 and 403 errors?

401 Unauthorized is the status code to return when the client provides no credentials or invalid credentials. 403 Forbidden is the status code to return when a client has valid credentials but not enough privileges to perform an action on a resource.

How would you send status code 401 from the server?

The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. The server generating a 401 response MUST send a WWW-Authenticate header field containing at least one challenge applicable to the target resource.

How do you resolve 401 unauthorized error in Postman?

Make sure that the URL is typed correctly. Verify the API documentation of the service you are trying to reach and make sure you have selected the right authorization type in Postman. Visit the service provider's page and look for a Sign in link. Enter your credentials and then try the page again.


4 Answers

By definition (see RFC 2616), the HTTP 302 response code is the redirect code. Without it, the location header may be ignored.

However, you can send an HTTP 401 response and still display output. Instead of redirecting the user to an error page, you could simply write your content you want to send in the HTTP body in the same request.

like image 177
David Chan Avatar answered Sep 21 '22 04:09

David Chan


I'm coming in very late here but I thought I'd add my two cents. As I understand it, the desire is to indicate that the user doesn't have the correct authorization and to prompt them to log in. Rudie understandably would like to return 401 Unauthorized (because the user needs to authorize by some mechanism, eg. logging in), and also forward them to the login page - but this is not very easy to accomplish and isn't supported out-of-the-box by most libraries. One solution is to display the login page in the body of the 401 response, as was suggested in another answer. However, let me take a look at this from the perspective of established/best practice.

Test case 1: Facebook

Navigating to a protected Facebook page (my user profile) while logged out results in a 404 Not Found response. Facebook serves up a general purpose "this page is not available" page, which also includes a login form. Interesting. Even more interesting: when I navigate to the "events" page, I'm served a 302 response which forwards to a login page (which returns a 200 response). So I guess their idea is to return 302 for pages that we know exist, but serve 404 for pages which may or may not exist (eg. to protect a user's privacy).

Test case 2: Google Inbox

Navigating to my inbox when I am logged out returns 302 and forwards me to a login page, similar to Facebook. I wasn't able to figure out how to make my Google+ profile private so no test data there...

Test case 3: Amazon.com

Navigating to my order history when I am logged out returns 302 and forwards me to a login page as before. Amazon has no concept of a "profile" page so I can't test that here either.

To summarize the test cases here, it seems to be best practice to return a 302 Found and forward to a login page if the user needs to log in (although I would argue 303 See Other is actually more appropriate). This is of course just in the case where a real human user needs to input a username and password in an html form. For other types of authentication (eg. basic, api key, etc), 401 Unauthorized is obviously the appropriate response. In this case there is no need to forward to a login page.

like image 30
tytk Avatar answered Sep 22 '22 04:09

tytk


3xx means Redirect
4xx means the browser did something wrong.

There's a reason why the codes are split up the way they are - they don't mix ;)

like image 23
Niet the Dark Absol Avatar answered Sep 19 '22 04:09

Niet the Dark Absol


In addition to the fine answers from Kolink and David (+1's), I would point out that you are attempting to change the semantics of the HTTP protocol by both returning a 401 AND telling the browser to redirect. This is not how the HTTP protocol is intended to work, and if you do find a way to get that result, HTTP clients will find the behavior of your service to be non-standard.

Either you send a 401 and allow the browser to deal with it, or you handle the situation differently (e.g. as one commenter suggested, redirect to a login page or perhaps to a page explaining why the user had no access).

like image 22
Eric J. Avatar answered Sep 21 '22 04:09

Eric J.