PHP $_SESSION not staying across localhost subdomains [duplicate] - php

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Allow php sessions to carry over to subdomains
Kind of complicated, but I've got 4 subversion repositories that I want to run side by side on my localhost for testing.
I set php.ini as so:
session.cookie_domain = ".localhost.com"
I setup my hosts file:
127.0.0.1 vader.localhost.com
127.0.0.1 luke.localhost.com
When I login, it sets the cookie correctly.
Name: PHPSESSID
Content: b0d3h7nh5ff40sms26q04oasq3
Domain: .localhost.com
Path: /
I set the $_SESSION variable on login:
$_SESSION['authorized'] = true;
Reload the page, the headers are correct:
Cookie PHPSESSID=b0d3h7nh5ff40sms26q04oasq3
Host vader.localhost.com
Referer http://vader.localhost.com/
But the $_SESSION variable is empty.
This all works fine if I remove the subdomain.
Thoughts?
EDIT:
Suhosin is NOT installed.
Also, someone asked for the full code for the session setting:
if (authenticate($dat['username'], $dat['password'])) {
session_start();
$_SESSION['authorized'] = true;
$_SESSION['username'] = $dat['username'];
$_SESSION['userType'] = findId('t_user', 'username', $dat['username'], 'userTypeId');
$_SESSION['userId'] = findId('t_user', 'username', $dat['username'], 'userId');
$_SESSION['contactId'] = findId('t_user', 'username', $dat['username'], 'userContactId');
array_push($reply, $reply);
$reply['authorized'] = true;
}

Found this answer from PHP Sessions across sub domains, it shall helps :)
I donĀ“t know if the problem still exists, but I just ran into the same
problem and solved it setting a session name before calling
session_set_cookie_params():
$some_name = session_name("some_name");
session_set_cookie_params(0, '/', '.some_domain.com');
session_start();
I have changed nothing in my php.ini but now everything is working
fine.

You might need to call session_write_close() to force a cookie to save before the script ends (or you redirect).
Check the default cookie storage place and see what is in the files. This is usually the /tmp directory on linux.
Stop storing cookies in files. Start storing them in encrypted cookies which will free you're server from the unneeded I/0 requests.

Related

How to transfer session main domain to sub-domain in php [duplicate]

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()

Codeigniter, xampp cookies not setting

I'm using the codeigniter with xampp on a windows 7 PC.
I'm trying to use codeigniter's built in cookies, but I can't seem to get my cookies to set/stay. I know that the cookie code is going off, it's just not actually saving.
Here's the cookie code:
$this->input->set_cookie('userID', $userID, time()+259200, 'http://localhost', '/');
After running this and on every page, I've included print_r($_COOKIE); to see any/all cookies that are being set, but nothing shows up.
Is there something I've missed?
According to the docs:
The expiration is set in seconds, which will be added to the current
time. Do not include the time, but rather only the number of seconds
from now that you wish the cookie to be valid. If the expiration is
set to zero the cookie will only last as long as the browser is open.
So your code should be like this:
$this->input->set_cookie('userID', $userID, 259200);
Also i recommend you to set domain name and cookie path in the config file.
Here's the solution for anyone else that runs into this problem:
Cookies cannot be created on localhost, you'll need to use http://127.0.0.1 instead.
Go into CI's application/config/config.php and change any references to localhost you might have and change them instead to http://127.0.0.1 and do the same for the cookies. Set the following variables as well:
$config['cookie_domain'] = "127.0.0.1";
$config['cookie_path'] = "/";
Then to store the cookie: $this->input->set_cookie('userID', $userID, 259200);

Using $_SESSION between pages that are in different directories

I was wondering how I would pass something using a session between pages that are in two separate directories. For example, if I had the following code, what would I need to add to make it work?
Page 1: directory\directory1\directory2\Page1.php
session_start();
$_SESSION['example'] = '123';
Page 2: directory\dir1\dir2\Page2.php
session_start();
echo $_SESSION['example'];
Your code should work if these pages are served within the same domain.
You do not have to session_start() in each page. Just write that, in a single file and share that file between the pages you want to hold the session in.
So, if you have page1.php and page2.php and session.php You can create session either in page1.php and check it in page two like: echo var_dump($_SESSION) and vise-versa
First of all, check if session-cookies are properly set. Some problems (e.g. Headers already sent) may cause your session cookie to not be set.
If this is working properly, you may have to change the session cookie parameters via session_set_cookie_params
By setting the second parameter (path) to /, the session cookie is valid for the root of your website and all subdirectories.
Example
session_set_cookie_params(0, '/');
The same settings can also be set in your php.ini or via ini_set(). See Session configuration
Note:
I'm not sure if these settings have any effect if session.autostart is enabled, in which case the cookie-header may already be sent before the changes are made.

PHP: Is it possible to set the domain when creating a session?

On mydomain.com if I run this code:
session_start();
$_SESSION['close_label'] = '1';
and then onspect the session cookie in my browser, it says:
domain: .mydomain.com
Is it possible to have it say:
domain: .someotherdomain.com
or not?
You cannot set cookies for a completely different domain. That would be a security nightmare. You can set cookies for the current domain and/or subdomains of it. That's all.

Session variables are not persisting between page loads

Can someone tell me why the session vars are not passing between pages? They were working up to 2 days ago. Now its not? There is a third party system that logs users in based on the third party system. I direct users to the login page with the return url. The third party system logs a user in and passes their id and a token generated on their end and returns them to my site with the id and the token in the url.
If sessions are not set i try and grab the id and the token from the url and set the sessions. (working) I then generate my own token to validate against the token passed from the third party system (working) when i go to click to another page the sessions i set are not empty (????)
Here is my code:
<?php
session_start();
// FUNCTION TO PASS THE URL THE USER IS ON SO THEY COME
// BACk TO THIS PAGE AFTER THE LOG IN. IF APPLICABLE
function curPageURL() {
$pageURL = 'http';
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
// DESTROY SESSION INFO IF TIMED OUT
if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
session_destroy(); // destroy session data in storage
session_unset(); // unset $_SESSION variable for the runtime
}
// SET THE SESSIONS WITH INFO PASSED FROM
// LOGIN PAGE SENT AS A GET
if(isset($_SESSION['ID']) && isset($_SESSION['token'])) {}else{
$_SESSION['ID'] = $_GET['ID'];
$_SESSION['token'] = $_GET['token'];
}
// GENERATE MY TOKEN TO MATCH THE LOGIN SYSTEM TOKEN
$userIP = $_SERVER['REMOTE_ADDR'];
$secretkey = 'A Unique Key For The Logged In User Matching the Login System Passed From mydomain.com/login.php';
$algorithm = 'md5';
$mm = date('m');
$dd = date('d');
$mmdd = $mm.$dd;
$mytoken = strtoupper(hash($algorithm, $secretkey.$_SESSION['ID'].$userIP.$mmdd));
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp
// THIS IS WHERE THINGS ARE GOING WRONG
// SESSION token IS NO LONG SET AFTER I Go To another page
// and my token isnt the same any more either because session ID
// is no longer set???
if($_SESSION['token']==$mytoken){}else{
header("location: https://mydomain.com/login.php?returnURL=".curPageURL());
}
?>
ok this is messed up. It has to be a problem on the hosting providers PHP setup i think because i created two pages. one called info with this code:
<?
session_start();
$_SESSION['ID'] = "112233";
$_SESSION['token'] = "mytoken";
print $_SESSION['ID'];
print $_SESSION['token'];
?>
info 2
and one called info2 with this code:
<?
session_start();
print $_SESSION['ID'];
print $_SESSION['token'];
?>
info
info created and printed the session ok. when i click the link to go to info2 the sessions dont print. Is this a hosting config problem?
As already mentioned, ensure you're calling session_start() on each page.
Additionally, are the scripts on different subdomains?? If they are you should set the INI value session.cookie_domain to .DOMAIN.EXT.
To further debug this whole situation, do some simple cookie watching. See if PHPSESSID is present as a cookie on both page requests, if it's not then this is your problem. You can't store cookies cross-domain unless you reconstruct them.
In response to your update, try doing this underneath your call to session_start():
echo session_id();
Confirm that it's the same on both pages. If not, check the value of session.cookie_domain like this:
echo ini_get('session.cookie_domain');
Is that set to anything? By default it should be blank, if it's set, especially not to your domain, this is the problem.
You can also try debugging the cookie value of PHPSESSID like I first suggested.
Check List
1. Make sure that you have used session_start(); in the next page.
2. Are you using .htaccess file?
if so remove the .htaccess file and check the same.
some time rewrite rules cause session probs...
3. If session is working fine and you have trouble only with token, then check the token sent in url is url_encoded.
it's not the hosting server issue...
check your URLs
if a user is login under "example.com" session will be stored for "example.com" and not "WWW.example.com" so if a link goes to www.example.com it will not have that session.
you can use htaccess to always set the url to "WWW.example.com" use below code for it
RewriteEngine On
RewriteCond %{HTTP_HOST} ^hemantjadhav.com$ [NC]
RewriteRule ^(.*)$ http://www.hemantjadhav.com/$1 [L,R=301]
(replace hemantjadhav with your domain name)
Check the size of the session file: (code taken from this post)
$sessionfile = ini_get('session.save_path') . '/' . 'sess_'.session_id();
echo 'session file: ', $sessionfile, ' ';
echo 'size: ', filesize($sessionfile), "\n";
If your session file has zero size, make sure there is still disk space available on your server. That was the problem I had.
Check disk space with df -h on a linux server.
The answer to this is it was a hosting configuration error. Hosting company changed something and it has worked ever since.
In my case the solution was to have different parameter names in $_GET and $_SESSION.
$_SESSION["businessid"] = $_GET["businessid"]; // Leads to problems with session.
$_SESSION["business_id"] = $_GET["businessid"]; //Works perfectly.
It sounds strange but that's my experience.
The only answer for this problem is to use session_start(); on the top of every page. It will work fine. Else you might need to contact your hosting provider about this problem.
I would add that I got caught up with the same problem, except that in my case page was behind Varnish caching proxy and I missed out that configuration had a line where cookies were allowed only on specific paths, otherwise they would get removed with the following directive:
unset req.http.cookie;
Dont forget to also check your proxy settings.
I had session.cookie_samesite = "Strict" in my runtime file and was trying to bounce my user from Oauth2.0 back to my site and the PHP session ID was getting erased when the redirects hit. I removed this from my runtime file and it works fine now.
For anyone else searching this in frustration - another thing to check is the cookie_secure setting in php.ini.
If cookie_secure=1, cookies will only be sent and persist on secure connections. In our case, the site was deployed to an environment that did not have an ssl setup yet.
Set cookie_secure back to its default (0) - or get the site secured.
Make sure both pages are on the same domain.
Even www.site.com is different than site.com
If the above solutions do not work I suggest you do the following right before you set the new session variables:
session_destroy();
session_start();
and THEN save the new session variables that were not persisting before
In case this helps others:
If sessions are closed (e.g. with session_write_close() or session_commit()), then anything written to a session after that is not persisted.
Re-opening a closed session during the same request seems at best an uncertain endeavor. If anything has been sent back to the client already, session_start() seems to fail (return false) and nothing written to $_SESSION is persisted even if errors are not thrown.
Some may wonder why one would close sessions intentionally in the first place - the reason is "performance". Session resources (e.g. files with file-based sessions) are locked while the session is "open" and so for the duration of handling a request by default unless the session is specifically closed. If a response is taking awhile on the server (e.g. a long-running report query), a user (or multi-threaded UI) cannot complete another session-locking request while one is already in progress - so effectively all the session-based requests stack up sequentially and users are stuck waiting (the opposite of what is wanted with most modern UIs). The best answer, in most of my cases, is to release (close) the session as soon as possible (typically just after is has been read for the first time when handling a request) and keep it open for the duration of the request handling only if one needs to write to the session later (cases which should be minimized for performance of course).
You did not call session_write_close()

Categories