I have read many forums (including this one) about passing session variables between subdomains, and I can't get this to work. Can someone explain what I am missing?
Step 1
In the php.ini file:
session.cookie_domain = ".mydomain.example"
Verified with phpinfo() that I am using the right php.ini file
Step 2
In page at www.mydomain.example set a session variable $_SESSION['a'], verify that it appears by calling it on the next page (it does). Click link to sub.mydomain.example.
Step 3
Page at sub.mydomain.example checks if session variable is set using:
$a = $_SESSION['a'];
if(!isset($_SESSION['a'])){
echo "Error: Session Variable not available";
}
Unfortunately I am getting my error message. What am I missing?
You must pass the session id as a cookie and set the same session id on the new domain
For example you can use this code
ini_set('session.cookie_domain', '.example.com');
$currentCookieParams = session_get_cookie_params();
$rootDomain = '.example.com';
session_set_cookie_params(
$currentCookieParams["lifetime"],
$currentCookieParams["path"],
$rootDomain,
$currentCookieParams["secure"],
$currentCookieParams["httponly"]
);
if(!empty($_SESSION)){
$cookieName = session_id();
setcookie('PHPSESSID', $cookieName, time() + 3600, '/', $rootDomain);
}
if(isset($_COOKIE['PHPSESSID'])){
session_name($_COOKIE['PHPSESSID']);
}
debugging.
is the thing you're missing.
first of all you have to watch HTTP headers to see what is going on and what cookies actually being set. You can use LiveHTTPHeaders Firefox addon or something. With such info you can find the problem. Without it noone can answer tour question "my sessions don't work"
It can prove your statement of proper domain setting in the session settings. Or disprove it.
It can reveal some other misconfiguring.
It may show you cookie being sent back by the browser - so you can be sure that is server side problem
To see the actual result of your code (instead of guessing based on the indirect consequences) always helps.
So, I went a different direction and used this entry which worked...
session_set_cookie_params(0, '/', '.mydomain.example');
session_start();
Related
I use PHP sessions (not cookies, except for session id cookie) for all user data, and when a user goes to their profile user.mydomain.example they are immediately "logged out" until then remove the subdomain.
Is there a way to accept sessions from all domains as long as its *.mydomain.example
Here are 4 options.
Place this in your php.ini:
session.cookie_domain = ".example.com"
Or in your .htaccess:
php_value session.cookie_domain .example.com
Or as the first thing in your script:
ini_set('session.cookie_domain', '.example.com' );
Or in your php-fpm pool configuration for your site:
php_value[session.cookie_domain] = .example.com
if(isset($_COOKIE['session_id']))
session_id($_COOKIE['session_id']);
Zend_Session::start(); //or session_start();
if(!isset($_COOKIE['session_id']))
setcookie('session_id', session_id(), 0, '/', '.yourdomain.example');
security be damned, if you are as frustrated with incomplete or bad answers as I am, this is your savior. It just works.
change the session name at the top of the core functions file
like
session_name('mysession');
then use the following code into the php page
session_set_cookie_params(0,"/",".example.com",FALSE,FALSE);
setcookie(session_name(), session_id(),0,"/","example.com");
session_start();
finally change the default session name of the subdomain and remove the default cookie in subdomain's core functions file
like:
/*default session name*/
session_name("mysession");
/*remove the PHPSESSID and default session name from subdomain's cookie*/
setcookie( "mysession", "",1,"/" );
setcookie( "PHPSESSID", "",1,"/" );
if you continue with using your cookie name as PHPSESSID ,just remove all the functions with
"mysession" string like session_name('mysession'), setcookie( "mysession", "",1,"/" );
then check your browser's existing cookies, just remove all the cookies of domain and subdomain, and repeat the process.
I know this is quite old - but to further expand on #CTT's suggestion - I needed to add a php.ini file in each sub-directory (that will be executing php code and requires the session) of my subdomain with the following text:
suhosin.session.cryptdocroot=Off
suhosin.cookie.cryptdocroot=Off
I hope this helps (it took me ages to figure this out).
Another option that worked for me: is to force the name of the session:
session_name("myWebsite");
session_start();
yes. ini_set is working. but remember to destroy all caches and cookies of the browser to see it works.
destroy all caches and cookies of your browser
in your xxx.example.com and yyy.example.com, your php files should start like this.
ini_set('session.cookie_domain', '.example.com' ); session_start();
I just had this problem and it turns out I was using different php.ini files for two different sub-domains. These ini files specified different session.save_path variables. For obvious reasons this needs to be the same for all sub-domains that need to share sessions.
Before session_start() use session_set_cookie_params() replacing .domain.example with your domain like this example:
session_set_cookie_params(0, '/', '.domain.example');
session_start();
Try This:
session_start();
$sessionId = session_id();
logged the user. When user will switch to other subdomain sent the session id in the URL like this user.mydomain.example/?id=$sessionId
$sessionId = $_GET['id'];
session_start($sessionId);
Now the user will get all the session values and stay logged in.
if(isset($_COOKIE['session_id']))
session_id($_COOKIE['session_id']);
Zend_Session::start(); //or session_start();
if(!isset($_COOKIE['session_id']))
setcookie('session_id', session_id(), 0, '/', '.yourdomain.example');
This is a good solution, but you cannot use it in all situations. For examples it will not work when you cannot rely on not-session cookies.
This actually MUST work if you use it correctly.
ini_set('session.cookie_domain', '.example.com' );
For example you need to put it before session_start() and also in all files that call session_start()
I created two files:
// /var/www/blah/index.php (www.example.com/blah/index.php)
session_set_cookie_params(0, '/blah');
session_start();
$_SESSION['hello'] = 1;
and
// /var/www/foo/index.php (www.example.com/foo/index.php)
session_set_cookie_params(0, '/foo');
session_start();
echo $_SESSION['hello'];
When opening the first, then the second in browser, I get 1.
Why is the same SESSION available in both?
It should not, according to session-set-cookie-params.
As I said in ##php on freenode:
The browser doesn't respect the session_set_cookie_params() because you have a valid PHPSESSID cookie and your browser keeps regenerating it. (because you visited the page before). Delete all your PHPSESSID cookies and try again.
I use PHP sessions (not cookies, except for session id cookie) for all user data, and when a user goes to their profile user.mydomain.example they are immediately "logged out" until then remove the subdomain.
Is there a way to accept sessions from all domains as long as its *.mydomain.example
Here are 4 options.
Place this in your php.ini:
session.cookie_domain = ".example.com"
Or in your .htaccess:
php_value session.cookie_domain .example.com
Or as the first thing in your script:
ini_set('session.cookie_domain', '.example.com' );
Or in your php-fpm pool configuration for your site:
php_value[session.cookie_domain] = .example.com
if(isset($_COOKIE['session_id']))
session_id($_COOKIE['session_id']);
Zend_Session::start(); //or session_start();
if(!isset($_COOKIE['session_id']))
setcookie('session_id', session_id(), 0, '/', '.yourdomain.example');
security be damned, if you are as frustrated with incomplete or bad answers as I am, this is your savior. It just works.
change the session name at the top of the core functions file
like
session_name('mysession');
then use the following code into the php page
session_set_cookie_params(0,"/",".example.com",FALSE,FALSE);
setcookie(session_name(), session_id(),0,"/","example.com");
session_start();
finally change the default session name of the subdomain and remove the default cookie in subdomain's core functions file
like:
/*default session name*/
session_name("mysession");
/*remove the PHPSESSID and default session name from subdomain's cookie*/
setcookie( "mysession", "",1,"/" );
setcookie( "PHPSESSID", "",1,"/" );
if you continue with using your cookie name as PHPSESSID ,just remove all the functions with
"mysession" string like session_name('mysession'), setcookie( "mysession", "",1,"/" );
then check your browser's existing cookies, just remove all the cookies of domain and subdomain, and repeat the process.
I know this is quite old - but to further expand on #CTT's suggestion - I needed to add a php.ini file in each sub-directory (that will be executing php code and requires the session) of my subdomain with the following text:
suhosin.session.cryptdocroot=Off
suhosin.cookie.cryptdocroot=Off
I hope this helps (it took me ages to figure this out).
Another option that worked for me: is to force the name of the session:
session_name("myWebsite");
session_start();
yes. ini_set is working. but remember to destroy all caches and cookies of the browser to see it works.
destroy all caches and cookies of your browser
in your xxx.example.com and yyy.example.com, your php files should start like this.
ini_set('session.cookie_domain', '.example.com' ); session_start();
I just had this problem and it turns out I was using different php.ini files for two different sub-domains. These ini files specified different session.save_path variables. For obvious reasons this needs to be the same for all sub-domains that need to share sessions.
Before session_start() use session_set_cookie_params() replacing .domain.example with your domain like this example:
session_set_cookie_params(0, '/', '.domain.example');
session_start();
Try This:
session_start();
$sessionId = session_id();
logged the user. When user will switch to other subdomain sent the session id in the URL like this user.mydomain.example/?id=$sessionId
$sessionId = $_GET['id'];
session_start($sessionId);
Now the user will get all the session values and stay logged in.
if(isset($_COOKIE['session_id']))
session_id($_COOKIE['session_id']);
Zend_Session::start(); //or session_start();
if(!isset($_COOKIE['session_id']))
setcookie('session_id', session_id(), 0, '/', '.yourdomain.example');
This is a good solution, but you cannot use it in all situations. For examples it will not work when you cannot rely on not-session cookies.
This actually MUST work if you use it correctly.
ini_set('session.cookie_domain', '.example.com' );
For example you need to put it before session_start() and also in all files that call session_start()
OK, I'm stumped, and have been staring at this for hours.
I'm setting a cookie at /access/login.php with the following code:
setcookie('username', $username, time() + 604800, '/');
When I try to logout, which is located at /access/logout.php (and rewritten to /access/logout), the cookie won't seem to unset. I've tried the following:
setcookie('username', false, time()-3600, '/');
setcookie('username', '', time()-3600, '/');
setcookie('username', '', 1, '/');
I've also tried to directly hit /access/logout.php, but it's not working.
Nothing shows up in the php logs.
Any suggestions? I'm not sure if I'm missing something, or what's going on, but it's been hours of staring at this code and trying to debug.
How are you determining if it unset? Keep in mind that setcookie() won't remove it from the $_COOKIE superglobal of the current script, so if you call setcookie() to unset it and then immediatly print_r($_COOKIE);, it will still show up until you refresh the page.
Try pasting javascript:alert(document.cookie); in your browser to verify you don't have multiple cookies saved. Clear all cookies for the domain you're working on to make to sure you're starting fresh. Also ini_set(E_ALL); to make sure you're not missing any notices.
Seems to be a server issue. My last domain was pretty relaxed on PHP error handling while the new domain shows every error. I'm using both sites side by side and the old one removes the cookie as it should.
Is there perhaps a timezone issue here? Have you tried setting using something farther in the past, like time() - (3600*24)? PHP's documentation says that the internal implementation for deleting cookies uses a timestamp of one year in the past.
Also, you should be able to use just setcookie('username', false); without passing an expiration timestamp, since that argument is optional. Maybe including it is confusing PHP somehow?
How you use cookies data in your application?
If you read the cookies and check if username is not false or not '', then setting it to false or '' will be sufficient, since your application will ignore the cookies value.
You better put some security in cookies value, to prevent user change it's value. You can take a look of CodeIgniter session library, see how CI protect the cookies value using hash. Unauthorized value change will detected and the cookies will be deleted.
Also, CI do this to kill the cookies:
// Kill the cookie
setcookie(
$this->cookie_name,
addslashes(serialize(array())),
(time() - 31500000),
$this->cookie_path,
$this->cookie_domain,
0
);
You can delete cookies from javascript as well. Check here http://www.php.net/manual/en/function.setcookie.php#96599
A simple and convenient way, is to use this additional functions:
function getCookie($name) {
if (!isset($_COOKIE[$name])) return false;
if ($_COOKIE[$name]=='null') $_COOKIE[$name]=false;
return $_COOKIE[$name];
}
function removeCookie($name) {
unset($_COOKIE[$name]);
setcookie($name, "null");
}
removing a cookie is simple:
removeCookie('MyCookie');
....
echo getCookie('MyCookie');
I had a similar issue.
I found that, for whatever reason, echoing something out of logout.php made it actually delete the cookie:
echo '{}';
setcookie('username', '', time()-3600, '/');
I had the same issue; I log out (and I'm logged out), manually reload the index.php and then I'm logged in again. Then when I log out, I'm properly logged out.
The log out is a simple link (index.php?task=logout). The task removes the user from the session, and "deletes" (set value '' and set expiry in the past) the cookie, but index.php will read the user's auth token from the cookie just after this (or all) task (as with normal operations). Which will reload the user. After the page is loaded the browser will show no cookie for the auth token. So I suspect the cookie gets written after page finish loading.
My simple solution was to not read the cookie if the task was set to logout.
use sessions for authentication, don't use raw cookies
http://www.php.net/manual/en/book.session.php
I use PHP sessions (not cookies, except for session id cookie) for all user data, and when a user goes to their profile user.mydomain.example they are immediately "logged out" until then remove the subdomain.
Is there a way to accept sessions from all domains as long as its *.mydomain.example
Here are 4 options.
Place this in your php.ini:
session.cookie_domain = ".example.com"
Or in your .htaccess:
php_value session.cookie_domain .example.com
Or as the first thing in your script:
ini_set('session.cookie_domain', '.example.com' );
Or in your php-fpm pool configuration for your site:
php_value[session.cookie_domain] = .example.com
if(isset($_COOKIE['session_id']))
session_id($_COOKIE['session_id']);
Zend_Session::start(); //or session_start();
if(!isset($_COOKIE['session_id']))
setcookie('session_id', session_id(), 0, '/', '.yourdomain.example');
security be damned, if you are as frustrated with incomplete or bad answers as I am, this is your savior. It just works.
change the session name at the top of the core functions file
like
session_name('mysession');
then use the following code into the php page
session_set_cookie_params(0,"/",".example.com",FALSE,FALSE);
setcookie(session_name(), session_id(),0,"/","example.com");
session_start();
finally change the default session name of the subdomain and remove the default cookie in subdomain's core functions file
like:
/*default session name*/
session_name("mysession");
/*remove the PHPSESSID and default session name from subdomain's cookie*/
setcookie( "mysession", "",1,"/" );
setcookie( "PHPSESSID", "",1,"/" );
if you continue with using your cookie name as PHPSESSID ,just remove all the functions with
"mysession" string like session_name('mysession'), setcookie( "mysession", "",1,"/" );
then check your browser's existing cookies, just remove all the cookies of domain and subdomain, and repeat the process.
I know this is quite old - but to further expand on #CTT's suggestion - I needed to add a php.ini file in each sub-directory (that will be executing php code and requires the session) of my subdomain with the following text:
suhosin.session.cryptdocroot=Off
suhosin.cookie.cryptdocroot=Off
I hope this helps (it took me ages to figure this out).
Another option that worked for me: is to force the name of the session:
session_name("myWebsite");
session_start();
yes. ini_set is working. but remember to destroy all caches and cookies of the browser to see it works.
destroy all caches and cookies of your browser
in your xxx.example.com and yyy.example.com, your php files should start like this.
ini_set('session.cookie_domain', '.example.com' ); session_start();
I just had this problem and it turns out I was using different php.ini files for two different sub-domains. These ini files specified different session.save_path variables. For obvious reasons this needs to be the same for all sub-domains that need to share sessions.
Before session_start() use session_set_cookie_params() replacing .domain.example with your domain like this example:
session_set_cookie_params(0, '/', '.domain.example');
session_start();
Try This:
session_start();
$sessionId = session_id();
logged the user. When user will switch to other subdomain sent the session id in the URL like this user.mydomain.example/?id=$sessionId
$sessionId = $_GET['id'];
session_start($sessionId);
Now the user will get all the session values and stay logged in.
if(isset($_COOKIE['session_id']))
session_id($_COOKIE['session_id']);
Zend_Session::start(); //or session_start();
if(!isset($_COOKIE['session_id']))
setcookie('session_id', session_id(), 0, '/', '.yourdomain.example');
This is a good solution, but you cannot use it in all situations. For examples it will not work when you cannot rely on not-session cookies.
This actually MUST work if you use it correctly.
ini_set('session.cookie_domain', '.example.com' );
For example you need to put it before session_start() and also in all files that call session_start()