edmassarani
edmassarani

Reputation: 298

Redirecting with header, but http code is always 200

So, I have a page that checks if the user is logged in and if he isn't they are redirected to the error page with code 403. This is the code I use to redirect:

header('Location: /error.php', true, 403);

But, instead of redirecting it only sets the code to 403. And if I try:

header('HTTP/1.1 403 FORBIDDEN');
header('Location: /error.php');

Then it redirects, but the code is 200... I'm really lost here and couldn't find anything that worked.

ps: this is my error.php page

<link rel="stylesheet" href="css/error.css">
<?php if (http_response_code() === 404) : ?>
<div class="error">404</div>
<br /><br />
<span class="info">File not found</span>
<img src="http://images2.layoutsparks.com/1/160030/too-much-tv-static.gif" class="static" />
<?php elseif (http_response_code() === 403) : ?>
<div class="error">403</div>
<br /><br />
<span class="info">Unauthorized access</span>
<img src="http://images2.layoutsparks.com/1/160030/too-much-tv-static.gif" class="static" />
<?php endif; ?>

Upvotes: 2

Views: 2546

Answers (4)

ivanivan
ivanivan

Reputation: 2215

You don't redirect - you simply generate the 403 (or whatever other error code is appropriate) and have Apache send the proper ErrorDocument.

https://httpd.apache.org/docs/2.4/mod/core.html#errordocument

EG -

ErrorDocument 403 /errors/forbidden.php?referrer=%{escape:%{HTTP_REFERER}}

in your Apache vhost config, or a .htaccess file.

Even Apache's docs note what one of the comments reflected about sending a status code followed by a redirect -

Note that when you specify an ErrorDocument that points to a remote URL (ie. anything with a method such as http in front of it), Apache HTTP Server will send a redirect to the client to tell it where to find the document, even if the document ends up being on the same server. This has several implications, the most important being that the client will not receive the original error status code, but instead will receive a redirect status code. This in turn can confuse web robots and other clients which try to determine if a URL is valid using the status code. In addition, if you use a remote URL in an ErrorDocument 401, the client will not know to prompt the user for a password since it will not receive the 401 status code. Therefore, if you use an ErrorDocument 401 directive, then it must refer to a local document.

Upvotes: 1

NineBerry
NineBerry

Reputation: 28499

Don't use redirection, but script reuse.

Redirection means "What you are looking for, can be found at a different place". You don't want to send the user to a different place. You want to tell them that they are not allowed to see that place where they tried to go.

Instead, use require to include the php script which should show information about an error to the user, without changing the URI.

if(detectedUserNotAllowed)
{
   header('HTTP/1.1 403 FORBIDDEN');
   require("error.php");
   exit();
}

Upvotes: 2

maio290
maio290

Reputation: 6732

You cannot redirect with a 403 code, browsers won't heed a location header if the status code is not one of the 3xx section.

This is found in RFC 7231:

For 3xx (Redirection) responses, the Location value refers to the preferred target resource for automatically redirecting the request.

Upvotes: 0

Felippe Duarte
Felippe Duarte

Reputation: 15131

From the docs:

From the docs: "The second special case is the "Location:" header. Not only does it send this header back to the browser, but it also returns a REDIRECT (302) status code to the browser unless the 201 or a 3xx status code has already been set.

http://php.net/manual/en/function.header.php

That being said, you can add the header in your error.php page

header("HTTP/1.0 403 Forbidden");

Upvotes: 3

Related Questions