I am writing a custom session handler and for the life of me I cannot get a cookie to set in it. I'm not outputting anything to the browser before I set the cookie but it still doesn't work. Its killing me.
The cookie will set if I set it in the script I define and call on the session handler with. If necessary I will post code. Any ideas people?
<?php
/* require the needed classes comment out what is not needed */
require_once("classes/sessionmanager.php");
require_once("classes/template.php");
require_once("classes/database.php");
$title=" "; //titlebar of the web browser
$description=" ";
$keywords=" "; //meta keywords
$menutype="default"; //default or customer, customer is elevated
$pagetitle="dflsfsf "; //title of the webpage
$pagebody=" "; //body of the webpage
$template=template::def_instance();
$database=database::def_instance();
$session=sessionmanager::def_instance();
$session->sessions();
session_start();
?>
and this is the one that actually sets the cookie for the session
function write($session_id,$session_data)
{
$session_id = mysql_real_escape_string($session_id);
$session_data = mysql_real_escape_string(serialize($session_data));
$expires = time() + 3600;
$user_ip = $_SERVER['REMOTE_ADDR'];
$bol = FALSE;
$time = time();
$newsession = FALSE;
$auth = FALSE;
$query = "SELECT * FROM 'sessions' WHERE 'expires' > '$time'";
$sessions_result = $this->query($query);
$newsession = $this->newsession_check($session_id,$sessions_result);
while($sessions_array = mysql_fetch_array($sessions_result) AND $auth = FALSE)
{
$session_array = $this->strip($session_array);
$auth = $this->auth_check($session_array,$session_id);
}
/* this is an authentic session. build queries and update it */
if($auth == TRUE AND $newsession == FALSE)
{
$session_data = mysql_real_escape_string($session_data);
$update_query1 = "UPDATE 'sessions' SET 'user_ip' = '$user_ip' WHERE 'session_id' = '$session_id'";
$update_query2 = "UPDATE 'sessions' SET 'data' = '$session_data' WHERE 'session_id = '$session_id'";
$update_query3 = "UPDATE 'sessions' SET 'expires' = '$expires' WHERE 'session_id' = '$session_id'";
$this->query($update_query1);
$this->query($update_query2);
$this->query($update_query3);
$bol = TRUE;
}
elseif($newsession == TRUE)
{
/* this is a new session, build and create it */
$random_number = $this->obtain_random();
$cookieval = hash("sha512",$random_number);
setcookie("rndn",$cookieval,$expires,'/');
$query = "INSERT INTO sessions VALUES('$session_id','0','$user_ip','$random_number','$session_data','$expires')";
$this->query($query);
//echo $cookieval."this is the cookie <<";
$bol = TRUE;
}
return $bol;
}
code updated. still no luck
for some reason if any html is echoed after the session manager is started the cookie is called after the html. this doesnt make any sense to me
The problem is likely in your if/else statements. You are using:
if($auth = TRUE AND $newsession = FALSE)
...
elseif($newsession = TRUE)
The use of a single = means that you are assigning values, not comparing them. You need to use == instead of =.
Change to this:
if($auth == TRUE AND $newsession == FALSE)
...
elseif($newsession == TRUE)
With the code that you have right now, the first if block of your code will run every time, so your setcookie() call is never reached.
setcookie() returns false if php can't add the header. So for debugging try something like
setcookie("rndn",$cookieval) or die('setcookie failed');
You can combine that with a test whether setcookie() is called in the first place
$rc = setcookie("rndn",$cookieval);
/* DEBUG-code don't forget to remove me */
error_log(sprintf("%s %s\n", date('Y-m-d H:i:s setcookie():'), $rc?'success':'failed'));
(or even better use a debugger like xdebug and e.g. netbeans as frontend).
Did you check the response headers in your browser? E.g. via the firebug extension. Perhaps the client receives the cookie header but doesn't accept it.
According to tour code, at least you have to set / directory in the cookie parameters.
But anyway, first of all you have to sniff cookies from the HTTP log. You can use Firebug to watch if server does set any cookie and if browser send any back
Related
I never worked with cookies before so I'm probably messing up really hard.
Thing is. I set a cookie and then try to echo it for testing. If I inspect my browser, it shows me the cookie is there, but the cookie being fetched is always one cookie previous to the one last created. Here is what I'm doing:
function set_cookie_test($user_id)
{
$this->load->helper('cookie');
$this->load->module('site_security');
$this->load->module('site_settings');
$now_time = time();
$one_day = 86400;
$one_week = $one_day * 7;
$one_week_ahead = $now_time + $one_week;
$data['cookie_code'] = $this->site_security->generate_random_string(128); // the cookie_code on the table is 128 chars long
$data['user_id'] = $user_id;
$data['expiry_date'] = $one_week_ahead;
$this->_insert($data);
$cookie_name = $this->site_settings->_get_cookie_name();
set_cookie($cookie_name, $value = $data['cookie_code'], $expire = $data['expiry_date'], $domain = '', $path = '/', $prefix = '', $secure = FALSE, $httponly = FALSE);
$cookieVal = get_cookie($cookie_name);
echo $cookieVal; die();
}
This is what happens after I log in (when I call this function)
As you can see, the cookie in the browser has a value of 8XvaQZjWX7... This is the current cookie, it matches my DB.
The previous cookie value in my db is the one being echoed out. I need to figure this out for the following reason:
Whenever I use sessions for the login, I set userdata so I can retrieve the user's info to display his name and avatar on the screen, for example.
I need to be able to do the same when I use cookies...
Any help is very much appreciated.
Is it possible to remove a cookie and set one with the same name but different value in one request? Here is the code I have so far, which works locally for me but not on the live server. The cookie is set from a query string and sometimes the cookie can be set externally (not HttpOnly), but on the live server, I will get a redirect loop and both cookies will be set.
if ($request->query->has('cookie')) {
$setCookie = $request->query->get('cookie');
$route = $request->getRequestUri();
$host = $request->getHost();
if (!$request->cookies->has('reference') || $request->cookies->get('reference') !== $setCookie){
$exp = new \DateTime();
$exp->modify('+3 months'); // cookie has three months to live
$r = new RedirectResponse($route);
$r->headers->clearCookie('reference');
$r->headers->setCookie(new Cookie('reference', $setCookie, $exp, '/', $host));
return $r;
}
}
So if the user goes to www.*******.com/?cookie=newvalue, I need any current cookie with the name 'reference' and a new cookie set with the value, 'newvalue'.
I am setting a cookie on one page with below code
setcookie(codeDone,true);
This works but then I reset it to false on another page
setcookie(codeDone,false);
But then, when I go back to the first page, before the part that sets it to true I have
if($_COOKIE['codeDone'] == true){
$cookie = $_COOKIE['codeDone'];
$done = false;
echo"cookie set to $cookie";
}
setcookie(codeDone,true);
For some reason the ocokie is set to true because the contents of this if are always executed
Why is the cookie returning true (1) if in the previous page i set it to false?
Cookies are only string-values.
The code below is an example for your case to handle string as boolean:
ob_start();
if (isset($_COOKIE['codeDone'])) {
//this is your magic
$result = filter_var($_COOKIE['codeDone'], FILTER_VALIDATE_BOOLEAN);
if ($result === true) {
$cookie = $_COOKIE['codeDone'];
$done = false;
echo "Current Cookie Status: ".$_COOKIE['codeDone'];
}
}
setcookie('codeDone', 'true');
ob_end_flush();
BTW: You cannot modify the header (setcookie) after executed echo. this is the reason why i use the output buffer (ob_start/ob_end_flush)
I am getting unknown issue that is i am not able to unset my session with the browser.
Here is my code that checks on every request:
if (isset($_SESSION["logid"])) {
$log = TRUE;
$logid = $_SESSION["logid"];
$session_id = $_SESSION["sid"];
} else {
$log = FALSE;
}
if (!isset($_COOKIE["cook"])) {
if ($log) {
unset($_SESSION["logid"]);
unset($_SESSION["sid"]);
$log = false;
}
$expire = time() + 60 * 60 * 24 * 30 * 2;
$data = array(
"ip" => $_SERVER['REMOTE_ADDR'],
"browser" => $_SERVER['HTTP_USER_AGENT'],
"create_time" => $now
);
$result = $db->insert("cookies", $data);
$cookie_id = $db->lastid;
$cookie_id = my_encrypt($cookie_id);
setcookie("cook", $cookie_id, $expire, "/");
} else {
$cookie_id = $_COOKIE["cook"];
}
and code for logging out is here
unset($_SESSION["logid"]);
unset($_SESSION["sid"]);
I don't want to unset/expire cookie named cook but i want to create it if cookie deleted manually or other reason so the code in first block does that.
Not quite sure I understand the issue, but maybe this will help. All browser instances (windows or tabs) share the same cookie jar. While this is rarely a problem in "real life" it plays havoc with developers because you, as a developer, may have many tabs open. If you want to test an application that changes cookies (such as a login or logout) you should close all instances of your browser and open only one instance, then test.
PROBLEM
I've got an admin panel. Currently only Mozilla is able to process log ins. Browsers like Chrome, IE, Opera won't even show any message carried through sessions thus no one is able to log in any browser but Mozilla.
SOME INFORMATION
I'm using PHP 5.3.6 on my server, PHP 5.3.5 on my local
computer.
My code is Object Oriented.
ini_set("session.use_only_cookies", 1); and
ini_set('session.cookie_secure', 1); are used in construction method
of my session class.
This website on SLL
Login process: First I gather all information from form, validate and gather data. After validation if everything is right, I send this data to login method in my session class.
public function login ($user) {
global $siteSettings;
if ($user) {
$this->id = $_SESSION['id'] = $user->id;
$this->username = $_SESSION['username'] = $user->username;
$this->fullName = $_SESSION['fullName'] = $user->fullName;
$this->group_id = $_SESSION['group_id'] = $user->group_id;
$this->groupName = $_SESSION['groupName'] = $user->groupName;
$this->lastLogin = $_SESSION['lastLogin'] = $user->lastLogin;
$this->isAdmin = $_SESSION['isAdmin'] = ($user->admin == 1) ? true : false;
$this->isAgent = $_SESSION['isAgent'] = ($user->agent == 1) ? true : false;
self::$language = $_SESSION['language'] = ($user->language != "" || $user->language != NULL) ? $user->language : self::$language;
if ($user->language != "" || $user->language != NULL) {
$_SESSION['language'] = $user->language;
}else {
if (!defined(DEFAULT_LANGUAGE)) {
$browserLang = "|".$_SERVER["HTTP_ACCEPT_LANGUAGE"];
$browserLang = getStringBetween($browserLang, "|","-", FALSE);
if (!file_exists(LANGUAGES.$browserLang.".php")) $browserLang = FALSE;
}
$_SESSION['language'] = ($browserLang) ? $browserLang : DEFAULT_LANGUAGE;
}
# When 2 Update session_id
$date = new DateTime("now");
$UpdateTime = $siteSettings->session->timeOut * 60;
$date->add(new DateInterval("PT".$UpdateTime."S"));
$_SESSION['SIDUpdateTime'] = $date->format("Y-m-d G:i:s");
# UPDATE LAST LOGIN & ADD SESSION ID
# Clear Fields
members::clearFields();
members::$fields['id'] = $_SESSION['id'];
members::$fields['lastLogin'] = date("Y.m.d G:i:s");
members::$fields['lastLoginIP'] = $_SERVER['REMOTE_ADDR'];
# GET THE SALT
$saltInfo = members::getData("id", "salt", members::$fields['id']);
# SETTING SESSION ID ENCRYPTION
crypt::setKey($saltInfo->salt);
members::$fields['sessionID'] = crypt::encode(session_id());
members::$fields['sessionIP'] = $_SERVER['REMOTE_ADDR'];
members::$fields['sessionAgent'] = $_SERVER['HTTP_USER_AGENT'];
members::save();
$this->loggedIn = true;
var_dump($_SESSION);
}
}
When I dumb the data I can see $_SESSION got some values.
Just to test it, I stopped the script where after var_dump($_SESSION); (added die();) I created test.php file and tried this;
<?php
ob_start();
session_start();
echo '<pre>';
var_dump($_SESSION);
echo '<pre>';
ob_end_flush();
?>
Output is array(0) {}
But when I try exactly the same thing with Mozilla, output of test.php is the way it should be (matching with login method's result in my session class).
I have tried from my local computer and I don't experience the same
problem.
I disabled all java script and jquery codes from the page just to
have no 'maybe' in my mind.
After dumping the data, script is stopped. That's why $_SESSION variable shouldn't change. For some reason when it is on the server only Mozilla is able to show expected result while other browsers shows NULL.
At this point I really don't know what to think of about this problem to try to solve it. All I can think of is, this problem is possibly related to server configuration. But then, PHP is server side programming. PHP shouldn't display different behavior for browsers like Jquery, CSS, HTML...
I'm sorry, I can't provide admin panel link. Considering this is an active admin panel. If necessary I could install it on another domain to let you try but I believe the information I gave above explains everything.
Thank you for your help in advance.
I had a similar problem... just enable the cookies.. so that after login the code to set the sessions will be executed and the sessions will be set. may be the sessions r not able to set...
also check this http://php.net/manual/en/function.session-cache-limiter.php
If something large doesn't work, trim it down, test & debug, and build up from there.
Does this work? (Run it twice).
<?php
session_start();
echo "Session ID: " . session_id() . "<br/>\n";
if (!isset($_SESSION['test']))
{
$_SESSION['test'] = "foobar";
echo "Setting session variable: ";
echo $_SESSION['test'];
}
else
{
echo "Restoring session variable: ";
echo $_SESSION['test'];
}
If this works in all browsers, it's got something to do with your code. An empty session might have something to do with a cookie that can't be written, for example. Also set error reporting to E_ALL | E_STRICT, so you'll see everything that goes wrong.
It turns out Mozilla FireFox is able to process some data but other browsers I tried with are not and therefore they reset the whole session with each page load.
I had no problem with my local computer but on the server I had sessions problem. I don't know why session_set_cookie_params(); and setcookie(); didn't work on the server so I had to code longer version;
private static function sessionLifeTime() {
global $siteSettings;
# HOW LONG WE WANT SESSIONS
$lifeTime = intval($siteSettings->session->timeOut) * 60;
if (isset($_SESSION['id']) && isset($_SESSION['lastActivity']) && (time() - $_SESSION['lastActivity'] > $lifeTime) ) {
// SEND INFORMATION TO USER
self::logout();
}
$_SESSION['lastActivity'] = time();
}
Replacing my method with the code above solved the problem.
Thank you all for your time, concern and interest.