302 redirect to non-HTTP protocol - php

I need to perform a 302 redirect with PHP. I'm trying with header location.
It works well with HTTP. But, the redirect does not work with a custom protocol. For example:
header ('Location: magplus://myaccountview/login/');
How I can fix it?

For some browsers, you will not be able to redirect to a protocol other than HTTP or HTTPS. There is nothing you can do about that specifically.
You can try to change the location in the browser client-side with JavaScript, if that is a possibility for your application. That also won't always work however.

Related

Sent Strict-Transport-Security header, but Chrome is still requesting via http

I'm running a new site on Google App Engine with a custom domain and I want to require all traffic to come through via https.
I created a test script at http://rublonde.com/tmp:
<?
header("Strict-Transport-Security: max-age=180; includeSubdomains");
print $_SERVER['HTTP_X_FORWARDED_PROTO'];
(The content of the site doesn't really match the domain name, I'm just temporarily using this domain as a custom domain so I can get the HTTPS header thing working.)
In Google App Engine, the HTTP_X_FORWARDED_PROTO will be either http or https. On the first load of this page, I assumed it would get the the HSTS header and then on subsequent loads of the page, Chrome should automatically be requesting the page via https.
Am I misunderstanding how HSTS works? Am I doing something wrong?
Ah, I realized that HSTS headers are ignored when sent over an http connection (I think because they need to be associated with a valid certificate that comes with the https connection).
https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security#HSTS_mechanism_overview
A server implements an HSTS policy by supplying a header over an HTTPS
connection (HSTS headers over HTTP are ignored).

Redirect HTTPS to HTTP in Controller

At the moment the redirect code redirects HTTPS → HTTPS. I tried stopping the page with die($url) to see if the PROTOCOL is HTTP and it was correct. But for some reason when I try PHP header location it redirects back to HTTPS protocol rather than HTTP
So when I use following code in my Zend predispatch method
header('Location: http://www.example.com/blogs/');
it redirects to https://www.example.com/blogs/ (HTTPS PROTOCOL)
whereas when I try
header("Refresh:0; url=http://www.example.com/blogs/");
it works fine. Meaning it redirects to HTTP protocol.
Note: The reason I need to do this inside the controller is that redirects depend on a special flagpole. I cannot do it with Apache config.
I have finally solved this issue.
The problem was the redirection headers were being overridden by the loadbalancer. So there was some sort of policy set that if someone tries to redirect URL from one protocol to another it will not allow that causing the redirect loop that i was experiencing.
The solution in my particular case was another custom header that was needed to be sent which allowed scheme override in the loadbalancer.

signed_request as $_GET not $_POST

The application I'm working on has rewrite rules in place to ensure that the user is always on https. In my fb application settings, I can define both the secure and nonsecure canvas page to use https (so no redirection will occur) but I cannot do the same on a tab page of the application. FB uses whatever protocol the user is running on as far as I can tell.
Because of this, when a user hits the application via http, mod_rewrite redirects the user to the https version. Redirects don't pass along form data. There was a thread I found that discussed using a proxy redirect but that doesn't seem to be working.
Is there some configuration setting I could use to turn my signed_request $_POST into a $_GET? Alternatively is there some api call I could make to get the signed_request? The facebook->getSignedRequest() simply looks in the $_REQUEST which due to the redirect contains no post data.
I'd do the redirect in PHP (using $_SERVER['HTTPS']) rather than via .htaccess, and do it after first saving the signed request data to the user's session.
I have the same problem here. When I visit the tab using HTTPS I get the signed_request just fine because there's not redirect happening.
I run another Facebook app on the same server and it uses an htaccess file to make sure the files are served over HTTPS. So, What I ended up doing was making sure that the sub folder I'm working in is excluded from the rewrite. Like so:
RewriteCond %{THE_REQUEST} !/my-app-folder
Then, in my PHP I do a check to see if the referer is HTTP. If it is not, I change the header to an HTTPS version of my app. Like so:
$referer = $_SERVER['HTTP_REFERER'];
if (substr($referer,0,5) != 'https') {
header("Location: https://www.facebook.com/myapp?sk=app_xxxxxxxxxxxxxx");
}
This is probably not fool proof, but once I click that like button, I definitely get the results I need. I tested this in the dreaded IE as well and it appears to be working there too.
Some browsers do redirect your request to https automatically if you have been on this particular site on https so if you are in http mode on facebook there is situation:
facebook requests http version of your app, browser redirect this request of facebook to https and POST data and thus signer_request are gone in this process...
i see this problem in chrome 23, if you delete browsing data (particulary "Deauthorize content licenses") app should run back on http

Various PHP questions

about this function:
function requireSSL() {
if($_SERVER['SERVER_PORT'] != 443) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: https://" . $_SERVER['HTTP_HOST'] .$_SERVER['REQUEST_URI']);
exit;
}
return false;
}
SSL requires port 443, so in this piece of code if not 443 then forced to use https? and if 443 it would automatically use https I assumed. What's the moved permanently used for?
The code header("Location: .");
What's use of the above, it's nothing more than telling it to stay at the same page. By default it should stay at the same page, isn't it redundant?
SSL requires port 443
Not always. That is the default port. HTTPS can be configured to run on other ports. A better way to check is:
if ( !isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) != 'on') {
}
What's the moved permanently used for?
From w3:
The requested resource has been assigned a new permanent URI and any
future references to this resource SHOULD use one of the returned
URIs
In other words, a browser should remember that the requested URI is moved and request the new URI anytime the user requests that old URI again.
By default it should stay at the same page, isn't it redundant?
That's not what the code is doing. It's redirecting to the https version when the user requests the non-https version.
This piece of code is redirecting the client to use https in case it does not use https. 301 tells the client to always use the new location.
The redirection is done via the Location header, and you are only partly right, the page is the same, but the connection is done via https and not http. If the client is already connected via https, the redirect does not occur.
1) HTTP/1.1 301 is for letting the browser and search engines know that the page has moved to https://example.com/thepage.php
2) This code is used for specific pages or sites that require SSL. Example: Shopping carts, banks, logins
HTTPS goes through port 443 by default. This code redirects the user, using the Location-header, to the HTTPS if the user is visiting through plain HTTP.
The 301 instructs the browser to always redirecting HTTP to HTTPS on succeeding requests on that URL.
In psuedo-code it does this:
if (user is NOT visiting through HTTPS)
redirect permanently to the same URL, but then through HTTPS
So no, it's not redundant, for if anyone visits that page using HTTPS, the body of the if-block will not be executed and no redirect takes place.
First of all, the function does what you think.
Let's go through each of those you want to learn more about:
header("HTTP/1.1 301 Moved Permanently");
This sets the HTTP response status code. Code: 301. Message: Moved Permanently. 301 is a permanent redirect, this just tells the browser (HTTP client), next time to use the new address directly instead of the requested one.
The new address is given with a Location: header.
header("Location: .");
This code is just plain wrong code. Don't expect that it works. I assume somebody wanted to redirect to the same page again, but this does not work this way. A Location: needs to be followed by an absolute URL, this is a relative URL and won't work. Absolute URLs always start with http:// or https:// and contain a host-name.

HTTP to HTTPS redirect not working on Apache with PHP

I have a script that handles several different redirects on a server with a snippet that looks like follows:
if($url == "http://www.url.com")
{header("Location: https://www.url.com/index.html");}
The script works exactly as intended with one issue - all of the https redirects end up redirecting to http (versus the https as defined).
Does anyone have any ideas what may be going on?
The server you redirect to has a redirect of its own to http.
Nothing you can do about it, unless you are administering that server.
There was something else going on with the server, but it's been a while so I can't remember what it was anymore.

Categories