tags:

views:

1477

answers:

16

I'm making a login system, but when a user logs in, it doesn't actually store any of the data i want it to in the session. I even checked the session's file, and it was empty. I have session_start(); on all the pages. what else could i be doing wrong. Heres the code for the two main pages.

the login code:

<?
if ($DEBUG == true) {
    error_reporting(E_ALL);
}
require "header.php";

require_once "dbinterface.php";
require_once "user.class.php";
require_once "config.inc.php";

$db = new db($DB['host'], $DB['user'], $DB['pass'], $DB['database']);

$u_result = $db->run("select user_id from users where user_name = '" . $db->escape($_POST['user_name']) . "'");

if ($u_result == false) {
    $url = 'Location: error.php?id=8';
    header($url);
}

if (count($u_result) < 1) {
    $url = 'Location: error.php?id=3';
    header($url);
}

$user = new user($u_result[0]['user_id']);

if ($user->match_password($_POST['pass']) == true) {
    $_SESSION['authenticated'] = true;
    $_SESSION['user_id'] = $u_result[0]['user_id'];
    $_SESSION['user'] = $user;
} else {
    $url = 'Location: error.php?id=4';
    header($url);
}
session_write_close();
header('Location: index.php');

?>

The header that gets included in every page:

<?php
if (!session_start()) {
    $url = "Location: error.php?id=13";
    header($url);
}
?>

A little background:

  • windows 7 (also tried on windows
  • server 2008, but currently on 7) PHP
  • 5 localy hosted problem is present
  • for everyone problem exists in all
  • browsers
A: 

Make sure your session.save_dir is set correctly. If you are on something like Media Temple where you are hosted in home/####/domains/html, it might not be set correctly and would not be saved.

Chacha102
Good point, but the session file being *empty* (rather than non-existent) makes me think it's not the problem in this case.
Arjan
A: 

Looks like the sessionID cookie is not being set

rmontagud
+1  A: 
  • first i suggest using

    error_reporting(E_ALL);

    in the begining of each file

  • Second, i think the problem is that you are including 2 session_starts, and what's going on, is that you might not be tracking the same session_id that you think.

dassouki
even with E_ALL error reporting on, it still doesn't spit out any errors. With the header() function, doesn't that redirect to the other page? cause that wouldn't make it have two session_starts. or does it more like, include the other page for processing at that spot?
The.Anti.9
Two calls to `session_start()` would not cause this problem. From the manual: "As of [version 4.3.3], calling session_start() while the session has already been started will result in an error of level E_NOTICE. Also, the second session start will simply be ignored."
zombat
+1  A: 

I have seen strange problems pop up when session_start() isn't the very first line of code on the page. Try moving your session_start()s above your includes and requires and see if that fixes it.

Jason
the only problem with that is that i need to have include 'user.class.php'; in before the session_start() because i'm storing an object in the session. which requires it to be before the session_start(); i'm thinking though that thats not going to be a viable option. So much for saving on queries.
The.Anti.9
+3  A: 

The SessionID is nowhere to be found. I had this problem once, sessions were being created like crazy but nothing got stored. (also, make sure You have proper write permissions to the session folder, once had a problem of that sort as well)

What You REALLY want to do, is

$sessid = session_start(); // for the beginning of a new session, and

session_start($sessid); // at the start request for each subsequent call until session is destroyed using session_destroy()

Of course, passing the $sessid variable between webpages is up to You. I prefer to use a &sessid= link additive ;> (that way I immediately know when something's gone awry ;P)

Remember, that the only way to ENSURE proper session restoring is to pass on the session ID. I know it's optional, and on most systems it should just work out-of-the-box, but sometimes it just doesn't, and there's simply NO guarantee about session behavior on shared hosting.

Just as a protip, try wrapping Your sessions in a class with 'magic' default handlers for __set() and __get(), might make Your life a little easier later on for verifying session data (the __call() handler is esp. useful for that). And make the constructor for the class expect a session id, with 0 (or -1 or whatever) being 'start new session', and make sure it screams errors if the ID isn't set explicitly - that'll alert You to obvious problems.

---------[ Edit

And oh, did I mention - in a shared environment with lots and lots of user requests, not naming your sessions explicitly can lead to bleed-through problems (one user being logged on as another). For the most part this doesn't happen, but if You have a really screwed-up hosting configuration, not naming Your sessions and relying on 'default behavior' can lead to multiple disasters at once. ;-)

Egon_Freeman
Google keeps the session id in the url.
Chacha102
Manually passing the session ID around is really not a good solution. That is what the session cookie is for.
staticsan
risks! even you have to regenerate the session id on every request for security reasons!
Sepehr Lajevardi
+4  A: 

Based on a comment in the PHP header() documention, I believe you need to do the following at the bottom of your file. header('Location: x'); is a special case of using the header() function, and it can interfere with session passing if a session has not had time to write before the header() call is issued. session_write_close() should fix that.

...    
session_write_close();
header('Location: index.php');
zombat
after reading the docs i thought this would do it, but it didn't seem to change anything.
The.Anti.9
+2  A: 

Long shot but worth mentionning:
Is PHP configured properly to handle sessions?
What's the phpinfo() output?

Pierre
A: 

Have a look at your php.ini settings. In particular, you want to set session.auto_start to 0 if you are manually doing session_start(). And if you're relying on the session cookie or transparant URL rewriting, you will need session.use_cookies=1 and/or session.use_trans_sid=1 as well.

staticsan
session.auto_start is at 0. session.use_cookies is at 1 and session.use_trans_sid = 0
The.Anti.9
+7  A: 

Hi,

Here are a couple suggestions (I don't really know what's happening and/or why ; so they are only suggestions ; maybe one will solve the problem ^^ ).

First of all, a couple of questions :
(They matter at least if none of these suggestion does the trick)

  • Which version of PHP / Apache are you using ?
  • Are you on Windows ? Linux ?
  • If you are on your "production" server, what hosting service are you using ? Maybe there's something special about it ?
  • Is the problem present for every one ?
    • Is there always a problem when you are browsing the site ?
    • Is it still present when you are accessing the site from another browser ?
    • What about from another computer ?
  • If you use something like var_dump($_SESSION); die; at the end of the script that sets data in session, what does it give ?


First idea : what if you set some header to disable caching by the browser ?
Stuff like this, for instance :

session_start();
header("Cache-control: private");


Second idea (at least if you are on windows) : did you try disabling you antivirus / firewall ?
Is the session cookie correctly created in the client's browser ?
If you are using sub-domains (or not) : is the cookie's domain OK ? What about it's expiration date ?


Third idea :

  • you said error_reporting is set to E_ALL, which is nice
  • what about display_errors ? Is it set to On so that errors get displayed ?
  • Is there anything interesting in PHP/Apache's error_log ?


Another one : Are you sure there is absolutly nothing that gets to the output before the session_start ? Not even white spaces ?


Yet another one : Are you sure about permissions on the directories / files ?

  • Permission to write in a directory means you can create new files, and/or delete old ones.
    • But, if I remember correctly, not that you can modify them
  • To modify files, you need write access on the files too
    • Actually, your webserver need write access to those files ^^

What are the permissions on the session's directory, and on the (empty) files that get created ?


I'm beginning to run out of ideas... With a bit of luck, maybe one of those will be the right one... Or help you find out what the right one would be !

Good luck !

Pascal MARTIN
the cache control thing didn't seem to make a difference. still having the same problem. i've tried in several browsers and on several computers and several servers and its the same problem. also i made sure display errors was on as well. Thanks for the suggestions though!
The.Anti.9
Oh :-( Too bad :-( If you're having the same problem with different browsers, on different computers and servers, there might be some kind of trouble with your code after all... Could you by any chance make an archive containing the full source-code, if it's not be big / hard to setup, so we can try to have a closer look ?
Pascal MARTIN
+1  A: 

I do have to agree with what Jason told earlier. Just add the session_start(); line before everything in the login script. Put it just after the session_start() function anywhere, not even in the header.

So modify your code like this

<?
session_start();
if ($DEBUG == true) {
    error_reporting(E_ALL);
}

followed by rest of your code...

Hope this solves the issue.

Christy John
Because he is storing class objects in the session, he needs to include the class defination before session_start().Personally, I convert class objects to strings before storing in session. You can convert them explicitly to XML.
dar7yl
hmmm, sorry I wasn't aware of that.
Christy John
i tried this anyways, but it still didn't solve my problem
The.Anti.9
+1  A: 

Check your includes for trailing lines. Sometime, a newline after the closing ?> will be output, and prevent the session from being created. That bit me seriously before I figured it out.

dar7yl
very good point, i've had this problem before, but its not the problem this time =/
The.Anti.9
+6  A: 

A probable cause is that execution continues after the header('Location...') statements. However it looks like you want it to stop, so you should add 'exit;' after redirecting to error.php. E.g.:

if ($u_result == false) {
    $url = 'Location: error.php?id=8';
    header($url);
    exit;
}

This could also be part of your problem, as you never go to error.php and see the error code. The last line is always executed:

header('Location: index.php');

And since header()'s default behavior is to replace existing headers, you always go to index.php no matter what.

daremon
+1  A: 

I've tested the code, and even replicated the ini settings you've got.

I made some simple objects to replace db and user. And because of what daremon said, if the any of the checks related to user and db fail, it will still show an empty index page( My test index printed the contents of the $_SESSION superglobal ).

So, is it possible that the error is in the classes db or user? Have you tested those? To see if the problem lies on those classes, it's simple a question of adding exit after every header call like daremon said.

Juan
+1  A: 
Huppie
A: 

Go to this Site and download the finished login system (great tutorial site!), it's the same as yours!

http://net.tutsplus.com/videos/screencasts/how-to-build-a-login-system-for-a-simple-website/

It may not answer your session problem, but solve the topic in an almost equal way ;D

elhombre
A: 

It doesn't sound like the cause for your problems here, but since you haven't found a solution yet, you might as well check if your host uses load balancing without syncing session data. This means your user could be sent to a different server for each request, and unless the session data directory is shared over all these servers, your session data will be lost.

Probably not the case here, but it caused me a serious headache a while ago, so I'm posting it just in case.