Why won't my cookie value change in PHP 5? - php

I have a website where the login info is optionally saved in a cookie (remember me checkbox at login) and when the user logs out, the value of the authentication cookie won't change to expire the cookie allowing logout.
The system does work correctly in both the dev and staging servers but for some reason will not work on our production server. We are running PHP 5 and Apache on all the servers.
Thanks.
Function to set cookie (minor edits for security):
function setCookieInfo($data,$expiry=0)
{
if($data === false)
{
//remove cookie!
$cookie = false;
$expiry = 100; //should be in the past enough!
}
else
{
$serial = base64_encode(serialize($data));
$hash = md5($XXX);
$cookie = $hash."---".$serial;
}
if($_SERVER['SERVER_NAME']=='localhost')
{
$domain = null;
}
else
{
$domain = '.'.$_SERVER['SERVER_NAME'];
}
return setcookie('Auth', $cookie, $expiry, $this->controller->base, $domain);
}

Posting some actual code might help, but I'll hazard a guess that it has something to do with the cookie domain being used.

Grab a traffic capture (e.g. www.fiddler2.com) of the SetCookie call that is intended to delete the cookie, and ensure that the Domain is valid and the expiration time/value is as expected.

Assuming you are using the PHP setcookie() function, make sure that the domain and path for the cookie are set correctly. Check PHP's documentation for the function for more information.
I might be able to tell you for sure if I had a little more info. Can you provide any more information without compromising too much about the project? How about the URLs of the dev, staging, and production servers, or at least examples of what they might be like?
Edit
Based upon the info you provided in your comment, I would recommend that you try using HTTP_HOST instead of SERVER_NAME. SERVER_NAME might be giving you a weird value depending upon your virtual server setup. Your path might not be quite right either - try a '/' and it should be available regardless of the subdirectory the user is in.
Also,
$this->controller->base
makes me think that you might be using CodeIgniter or Kohana. If so, you might consider using their cookie helpers.

Related

Login not working sometime in cakephp

I have customers_contoller.php in frontend
function login() {
if(!empty($this->data)) {
# Call function from Customer to insert Registration Data
$loginData = ClassRegistry::init('Customer')->checkLogin($this->data['email'], $this->data['password']);
if(isset($loginData) && !empty($loginData)) {
$this->Session->write('Session.userid',$loginData['Customer']['id']);
$this->Session->write('Session.email',$loginData['Customer']['email']);
$this->redirect(HTTP_PATH."my-profile");
exit;
} else {
$this->Session->setFlash('Please enter valid Username/Password','default',array('class'=>'flash_bad'));
$this->redirect(HTTP_PATH."customer/login");
exit;
}
}
}
and in model customer.php,
function checkLogin($email,$password) {
$loginData = $this->find('first', array('conditions' => array('Customer.email' => $email, 'Customer.password' => sha1($password), 'Customer.is_active' => 'Yes')));
return $loginData;
}
most of time Login working fine, but sometime login not working and also doesn't get Error Message. Only refresh page every time on login.
I have just check all this things i found that when i can't login in my website at that time browser's cache show '/app/' for Session path but i have set actual Session path in before_filter() function in app_controller.php using $this->Session->path = '/';
I just remove all the browser's cache and try for login, now it is working fine.
Can anyone explain me what is the issue?
it occurs randomly so i can't find root of the issue.
Possible reason of your problem is that Session is lost because of improper Cookie Path transmitted to browser. It may be happened randomly because of mixing of Session binding strategies of PHP (like by GET-parameter or by Cookies).
You have wrongly set up $this->Session->path parameter. It maps to session.cookie_path option of PHP. See quite similar example in this post.
session.cookie_path should exclude protocol, host and eventually port, so leave just root of you website '/':
$this->Session->path = '/';
See also description of Domain and Path options of cookies.
EDIT: In order to further investigate reason of Session misconfiguration, debug SessionComponent and CakeSession classes near $base argument passed to constructor:
/cake/libs/controller/components/session.php
/cake/libs/cake_session.php
I guess it was somehow passed wrongly, and you received /app/ cookie path in the browser.
For anyone else that may be interested, I had a similar problem on a new user's machine. It turned out that the machine was not syncing correctly with the internet time, and the machine had the date set to one day in the future. No errors were displayed, but the Auth session was destroyed on redirect, and I would always be redirected to the login page. Updating the time on the computer and restarting Chrome helped.
(Strangely, this wasn't a problem in Firefox.)

Having trouble making a PHP cookie stick

I'm trying to create a temporary login system for a site. I'm using cookies rather than a database as it is merely for FED testing but for some reason my cookies are not sticking :(
I know I'm posting fine because the header function works
if ($_POST['login'] == 1) {
if (($user=="name") && ($pass=="secret")) {
setcookie("seeker", "1", time()+3600);
header('Location: ../index.php?');
} else echo '<i>Incorrect username/password.</i>';
}
Try a full cookie setting with a larger expiry value:
setcookie('seeker', 1, time()+86400, '/', '.example.com');
The path setting may be the reason. If you're setting the cookie in a script in example.com/subdir/script.php, then the cookie will using /subdir as its path, and not show up for scripts running in different directories.
You should also consider using PHP Sessions. It will set the cookies for you automatically.

PHP Cookies works well on localhost, but it's not working on live server

Note: This issue is already solved,
finally I found that it's not cookies
problem, the problem is on
unserialize() function. The serialized
cookie which being the parameter of
that function must be stripslash-ed
first.
Hi there, I have a problem here about PHP Cookies. I'm using PHP Cookies to save user preferences. I've tested my code on my local machine (localhost using XAMPP). Everything's works very well, including the cookies. But when I uploaded it to the live server, the cookies not working at all. It seems that the setcookie() function do not write the cookie value. I've tested by echo-ing the cookie value both on my localhost and on my live server. $_COOKIE[] value on localhost is showing but not with the one in the live server.
I thought maybe it's related to the $expire time zone like the one's in this post http://anupraj.com.np/index.php/php-cookies-not-working-php-cookie-tutorial-and-scirpt/14 . But then I realized that I've set the cookies to expire in 1 month, not only in one hour like on that blog post. So I think that's not the case.
This is the content of setting.php
<?php
$defaultSettings['default_post_to'] = 'both';
$defaultSettings['timesince_style'] = 'simplify';
...
$defaultSettings['display_geo_info'] = 'true';
$defaultSettings['enable_javascript'] = 'true';
if(!isset($_COOKIE['settings'])){
setcookie("settings", serialize($defaultSettings), time()+3600*24*30);
header('Location: index.php');
}
$setting = unserialize($_COOKIE['settings']);
?>
And this is content of index.php
<?php
/*
ini_set ("display_errors", "1");
error_reporting(E_ALL);
*/
session_start();
require_once("settings.php"); // Settings files
require_once('varlib.php'); // Get all possible passed variable
require_once('auth.php'); // Check for channel login status
// If inputbar form submitted
if( $_POST['inputbox'] ){
...
}
else{
echo "SETTING COOKIE: <br/><br/>";
// This print_r is only showing the $_COOKIE value (which is stored on $setting) on localhost but no on live server
print_r($setting);
switch( $com ){
...
}
}
?>
I've search about it everywhere (Google, stackoverflow, asking friends on twiiter/FB) still no solutions
I hope some body could give me the solution here
Thanks :)
Look at both path and domain parameters for the setcookie function.
Reference: setcookie # PHP docs http://php.net/manual/en/function.setcookie.php
Try this to set your cookie:
if ($on_localhost) { // change this
$domain = '.localhost';
} else {
$domain = '.webhoster.com'; // change this
}
setcookie(
'settings',
serialize($defaultSettings),
time()+3600*24*30,
'/', // this is the path
$domain // this is the domain
);
Good luck!
While applying solutions we get forgot the basic of Cookies.
Cookies are like headers. Like the headers, it should be sent before any output generates. then only it sets successfully. I have struggled a lot for this problem but when i went through the basics this problem got solved quickly.
this syntax will be enough to solve this problem...
setcookie(
'settings',
serialize($defaultSettings),
time()+3600*24*30,
'/' // this is the path
);
Try this:
setcookie("settings", serialize($defaultSettings), time()+3600*24*30, '/'); // added path
Also, could it be that serialize($defaultSettings) result is too large?
Try exit() after the Location-header.
A Location-header does not prevent a PHP-script from executing further instructions, maybe there is something executed after the header that causes the misbehaviour.
Probably your server time is not correct therefore Cookeis are not working on server.
Try this:
setcookie("settings", serialize($defaultSettings), 0);
Setting expiration to zero will fix your issue in this case. or update your server time.
Only initialize the ob_start() method before setcookie(). most of the developer ob_start() method include in config file.

how to test authentication system?

EDIT: After a complaint about assigning myself the answer, I want to update that the answers provided were not satisfactory. No one came out and explicitly said this is your problem, do this and you will have a resolution. Mere suggestions are not sufficient to merit a bounty award. Lastly, the problem was with server settings and after doing some research on server sessions and looking at Stackoverflow/Serverfault I was able to determine how to best resolve this problem. Therefore, I did not feel it was unjust to mark my own answer as the correct one.
I have a php based authentication system which relies on LDAP to verify identity and uses sessions to maintain users authenticated status.
Lately I noticed that it appears to be pushing me back to the login page like my session expired. The problem is that it does not appear to be for any specific reason that I have noticed and I am not sure how to debug/test something like this.
Here is my authentication function which starts the session:
function authenticateUser($user, $password){
//assuming ldap connection and verification of user login/pass
//this is what will happen with authenticate user which is called
//when user submits login/pass on authentication form.
$_SESSION['id'] = $uID;
$time = time();
$_SESSION['time'] = $time;
$_SESSION['lastActivity'] = $time;
$_SESSION['expiration'] = $time+$cookieExpiration;
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
$_SESSION['secret'] = md5(rand());
$_SESSION['userHash'] = getSessionHash();
$_SESSION['firstLogin'] = isFirstLogin($user);
//assign cookie to user and log authentication
giveCookie("userHash", $_SESSION['userHash'],0);
logAuthenticationAttempt($user, $_SERVER['REMOTE_ADDR'], 1);
return true;
}//end authenticateUser
Give cookie function:
function giveCookie($name, $value, $expiration=0){
global $path, $site;
setcookie("userHash", $_SESSION['userHash'], $expiration, $path, $site, true, true);
}//end giveCookie
Here is my function which is called on each page to verify the user is authenticated before allowing them to proceed with action requiring authenticated status:
function isValidUser(){
global $links; global $userName; global $userID; global $cookieExpiration;
if(isset($_COOKIE['userHash']) and isset($_SESSION['userHash'])){
if($_COOKIE['userHash'] == $_SESSION['userHash']){
$userName = $_SESSION['nameN'];
$userID = $_SESSION['id'];
//update userHash cookie for additinoal expiration time this way session
$time = time();
$expiration = $time+$cookieExpiration;
$_SESSION['lastActivity'] = $time;
giveCookie("userHash", $_SESSION['userHash'],0);
$_SESSION['expiration'] = $expiration;
return true;
}
}
return false;
}//end isvalidUser()
Any advice or feedback on how to test this would be appreciated. I am looking to figure out why occasionally after performing some action I get pushed back to the login page.
On a page which request authentication what I do at the top is the following:
if(!isValidUser()){changePage($links['login']."?refer=".$links['requestHelp']);}
//note: changePage is just a function for header("location: somepage.php");
You seem to be confusing authentication, authorization and session management. If you want to test all 3 then you'll need some sort of automated test tool capable of scriptable, stateful HTTP session replay (e.g. http::recorder / www::mechaninze with Perl).
OTOH if you want to investigate the session management using your deployed application, then I'd recommend instrumenting the login page to capture information about the current session and how the user got routed there. You should also consider logging the session cookie on the webserver.
Not sure what testing software you use at the moment, but I'd strongly recommend Selenium. It allows you to run scripted tests through the browser, effectively simulating what an end user would do and see.
Write a functional test. You can use SimpleTest's WebTestCase for stuff like this. See the documentation at: http://www.simpletest.org/en/web_tester_documentation.html
Of course, you could also try to break the code down into smaller bits that can easier be tested individually. Right now, your authentication system is tightly coupled to the server state (eg. the session management). You could decouple the two and thus be able to test the authentication system in a unit test, rather than a functional test.
The server is probably overwriting their session cookie, which will change the session hash and then it won't equal the cookie they have clientside. You appear to be overthinking this. You don't need to set a cookie on their system to verify them. The $_SESSION var will handle it all for you.
If they pass the challenge, then they have a $_SESSION var that is set that gives them auth levels.
Don't pass $_SESSION off to other vars like you are. Don't go $username = $_SESSION['username'] because now you have a var that is nonsecure ($username) that could have secured data in it. But it might not.
Whenever you are displaying session info, make sure it came from the horse's mouth.
Take a deep look at session.configuration
i would (if your not willing to think over your concept) change the isValidUser to log what ever you can get before return false
function isValidUser(){
global $cookieExpiration; // since $links isn't used and $userName and $userId come from $_SESSION no need for global there
if( (isset($_COOKIE['userHash']) and isset($_SESSION['userHash']))
and ($_COOKIE['userHash'] == $_SESSION['userHash']) ){
$userName = $_SESSION['nameN']; // why these lines?
$userID = $_SESSION['id']; // see above
//update userHash cookie for additinoal expiration time this way session
$time = time();
$expiration = $time+$cookieExpiration;
$_SESSION['lastActivity'] = $time;
giveCookie("userHash", $_SESSION['userHash'],0);
$_SESSION['expiration'] = $expiration;
return true;
}
// $logger ist just an example an could be a p.e Zend_Logger Object
$logger->debug($_SESSION); // serialize if needed
$logger->debug($_COOKIE); // serialize if needed
$logger->err(error_get_last());
return false;
}//end isvalidUser()
And are you sure you called session_start() before isValidUser()
It appears that this was a simple misconfiguration of the server itself. Being that this server environment is a shared environment for hundreds of sites, I do not have ability to modify server wide settings in php.ini and the like.
What I was able to do though is...
session_set_cookie_params(time()+$expiration, $path, $domain, true, true);
This has resolved the issue, it appears before the session expiration was not set properly and this will set it accordingly for this specific application.

How to set a cookie in php?

I set a cookie and then check if exist like this
if(isset($_COOKIE["fan"]))
{
//Do Nothing
}
else
{
$cookie = "yes";
$expire=time()+60*60*24*30;
setcookie("fan", $cookie, $expire);
include_once("../inc/functions.php");
echo fan_page();
}
When I test on my local machine, it works, but when i upload to production server, it doesn't work.
What am I doing wrong?
Thanks In Advance!
Marc
You probably need to set the domain for the cookie. Locally it defaults, but in production you may come across some issues if it's not set explicitly.
See the arguments for setcookie; http://www.php.net/manual/en/function.setcookie.php
I also suggest looking in your browser cache to see if it is being set.
A cookie set for one path/hostname may override a cookie set for another path/hostname even if it is newer.
For instance, if there is already a cookie set for "www.example.com" and you set one for "example.com", when you read back the same cookie you'll get the one that was set for "www.example.com".
Try setting the cookie for the more specific hostname.
This may be part of the issue.

Categories