PHP: SESSION lost on SUBDOMAIN
I solve my problem thanks to this link PHP Sessions across sub domains
PHP:
<?php
session_set_cookie_params(0, '/', '.mywebsite.com');
session_start();
//Code...
?>
PHP session is getting reset between subdomains
My suspect is the suhoshin project's session encryption feature, this patchset is included in most debian based systems. It can be configured to encode the session file's content with a key generated from various sources, to protect the session contents from other php scripts running on the same machine (shared hosting) or session hijacking. One of the sources is the docroot (enabled by default) which is usually different on every subdomain.
Check if its installed
A simple phpinfo()
will report the extension and it's settings, look for a block named suhosin
and below that see if suhosin.session.encrypt
and suhosin.session.cryptdocroot
is on
Disabling the encryption
Obviously you can edit your php.ini to disable the whole encryption or only the docroot part if you have access to the server.
If you don't, and the server is running apache, try disabling it in the .htaccess
file of your php app's root like this:
php_flag "suhosin.session.cryptdocroot" 0
If its working you should see the difference in the phpinfo() output. (Local value column)
If your host doesn't allow a .htaccess
file, you can set the same variable in php, but its important to do it before session_start()
. Hopefully you have some kind of a front controller to place this in.
ini_set('suhosin.session.cryptdocroot', 0);
phpinfo();
The output of the phpinf should be same as in the .htaccess
method, cryptdocroot line with an "Off" local value.
PHP Session variables lost either with www or without
www.example.com
and example.com
are NOT the same website. They usually are, but only by convention. www.example.com
is a subdomain of example.com
For this reason, cookies set on example.com
will NOT be used on www.example.com
and vice versa, because it would be unsafe to assume they are the same thing.
You can override this behaviour to some extent by allowing the session cookie to work on all subdomains as well as the main domain by setting the php.ini setting session.cookie_domain
to .example.com
(replace with your own domain name, of course)
PHP $_SESSION across subdomains
.htaccess on api.example.com
# CORS Headers (add this)
<ifModule mod_headers.c>
Header add Access-Control-Allow-Origin "http://example.com"
## Post the domain that will be doing the XHR requests
Header add Access-Control-Allow-Credentials: "true"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"
</ifModule>
<Limit GET POST PUT DELETE>
Allow from all
</Limit>
example.com
Post the following in the header of your main website
ini_set('session.cookie_domain', '.example.com' );
session_start();
XHR Request
Now we need to post the credentials from example.com to api.example.com I'm using AngularJS with this
$http({
method: 'GET',
url: '//api.example.com/auth/',
xhrFields: {
withCredentials: true
},
crossDomain: true
}).success....
Also change your config to allow sending with Credentials
.config(function ($routeProvider, $httpProvider) {
$httpProvider.defaults.withCredentials = true;
//rest of route code
PHP session lost after redirect
First, carry out these usual checks:
- Make sure
session_start();
is called before any sessions are being called. So a safe bet would be to put it at the beginning of your page, immediately after the opening<?php
declaration before anything else. Also ensure there are no whitespaces/tabs before the opening<?php
declaration. - After the
header
redirect, end the current script usingexit();
(Others have also suggestedsession_write_close();
andsession_regenerate_id(true)
, you can try those as well, but I'd useexit();
) - Make sure cookies are enabled in the browser you are using to test it on.
- Ensure
register_globals
is off, you can check this on thephp.ini
file and also usingphpinfo()
. Refer to this as to how to turn it off. - Make sure you didn't delete or empty the session
- Make sure the key in your
$_SESSION
superglobal array is not overwritten anywhere - Make sure you redirect to the same domain. So redirecting from a
www.yourdomain.com
toyourdomain.com
doesn't carry the session forward. - Make sure your file extension is
.php
(it happens!)
Now, these are the most common mistakes, but if they didn't do the trick, the problem is most likely to do with your hosting company. If everything works on localhost
but not on your remote/testing server, then this is most likely the culprit. So check the knowledge base of your hosting provider (also try their forums etc). For companies like FatCow and iPage, they require you to specify session_save_path
. So like this:
session_save_path('"your home directory path"/cgi-bin/tmp');
session_start();
(replace "your home directory path" with your actual home directory path. This is usually within your control panel (or equivalent), but you can also create a test.php
file on your root directory and type:
<?php echo $_SERVER['SCRIPT_FILENAME']; ?>
The bit before 'test.php' is your home directory path. And of course, make sure that the folder actually exists within your root directory. (Some programs do not upload empty folders when synchronizing)
Related Topics
Mysqli Prepare Statement - Returning False, But Why
Passing Data via Modal Bootstrap and Getting PHP Variable
Mail(): Smtp Server Response: 550 the Address Is Not Valid Error on Hmailserver
How to Check If a User Is Logged-In in PHP
PHP Function with Optional Parameters
Using Clean Urls in Restful API
Laravel Eager Loading - Load Only Specific Columns
Token Was Deauthenticated After Trying to Refresh It
Parse Math Operations with PHP
How to Find Timezone Id from Ip Address/Country Name in PHP
Mysqli Prepared Statement Num_Rows Returns 0 While Query Returns Greater Than 0