Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sessions and php redirect doesn't work

I am making a PHP script check.php that checks if a user is logged in. There is only one user, so the password is written directly in the php code. The check.php is included at the top (line 1) of every relevant page with the line <? include "check.php"; ?>.

The code

I have removed the password and the domain name. Apart from that the following is my code. The point here is that you type in a password at a login page, and then send it by POST to this script.

If the password is correct xxx, the session login will store true.

If the password is not correct, but is set, meaning the user typed in something wrong, any existing session is ended with session_destroy(), meaning he is logged out.

If he reaches a page but is not logged in, the session login should be false or not set, meaning that the } elseif(!($_SESSION['login'])) { will be used.

Lastly, if he clicks a logout button he is send to this script with the url: check.php?logout=true. The logout=true should be caught in the $_GET in the final elseif statement, and the session should be ended in there.

<?
ob_start();
session_start();


if($_POST['password'] == 'xxx') {   // Correct password

    $_SESSION['login'] = true;
    header("Location: http://www.url.com/administration/index.php");

} elseif (isset($_POST['password'])) {  // Wrong password

    session_destroy();
    header("Location: http://www.url.com/administration/login.php?true");

} elseif(!($_SESSION['login'])) {   // Check at every page

    header("Location: http://www.url.com/administration/login.php");

} elseif($_GET['logout']) { // Log out

    session_destroy();
    header("Location: http://www.url.com/");

}
ob_flush();
?>

The problem

In every if statement I try to redirect. I use the header("Location:...), but it doesn't work in any of the cases. Because the header command must be the first request to be send to the browser according to the specs, I used the ob_start(); and ob_flush(); as described here. It doesn't work with or without these.

Also there is a problem with the session that will not store content. I can't store true in the session of some reason. Is there a problem with my code that makes it fail?

As a test I have tried to write an echo command in every if / ifelse statement. From that I found that the script always enters the third statement - the one with the !($_SESSION['login']).

The question

So far so good. This tells me that the script is able to detect that the session is not set.
The two problems that remain are:

  • WHY the redirect in a statement doesn't work, since no redirect happens, and
  • WHY the session can't be set in the first place.

Any advice will be appreciated.


Update 1

To make it clear what happens (and what doesn't happen) I have put in some echos at different spots. This snippet of the above code with some additional echos:

...
echo "Input: " . $_POST['password'];
echo "<br>Session before: " . $_SESSION['login'];

if($_POST['password'] == 'xxxx') {  // Correct password

    $_SESSION['login'] = true;
    header("Location: http://www.url.com/administration/index.php");
    echo "<br>Session after: " . $_SESSION['login'];
    echo "<br>The first if works";

} ...

returns the following output:

Input: xxxx
Session before:
Session after: 1
The first if works

(The xxxx is the password; and it is correct.)

This is a situation where you are loggin in. You have just written the password and has been sent to the check.php.

So, I can see here that it accesses the first if as it is supposed to. And the session is correctly set to true (or 1). When I refresh the page the session is not set anymore though. Shouldn't it be?

And the header redirect clearly doesn't do anything.


Update 2

So, thanks to the answer from @EmilF below, I found that my session id - which I could print to the screen with echo session_id(); - changes at every page shift or page refresh to some new random number it seems. I looks as if the data stored in the session is then forgotten, because the new session id points somewhere else.

By using:

<?
session_id('cutckilc16fm3h66k1amrrls96');
session_start();
...

where cutckilc16fm3h66k1amrrls96 is just a random number, the session id is fixed, and the stored data can now be retrieved again after page refresh. This works quite well; though still a bit odd it is necessary.

Now I only need the header redirect to work...

Well, this smells like something that has been shut off. The session and the header functionality are changed. Maybe this is some PHP setting from the host. Something that blocks the header request.

To be continued...

Update 3 - solved

See my answer below.

Some strange symbols are created in the beginning of the file when I change the file into another coding format, e.g. from ANSI to UTF-8. The symbols created are , and I cannot see them in my own editor. Because they are in front of the php script they prevent the header and session_start() to work proporly. Why they are created there is still a mystery to me.

like image 206
Steeven Avatar asked Jul 14 '12 18:07

Steeven


3 Answers

Okey, let’s list everything you can debug here, mentioning also stuff you already did (so other people can read it):

  • Do you have something like HTTP Header installed? Then you can see if the Location: header is sent to your browser or not.
  • I suppose you do not get any error messages, do you? Have you set error_reporting(E_ALL);?
  • Try doing var_dump() for the $_POST array.
  • Do you also have something to check cookies with in your browser? I usually use the Firefox web-developer toolbar plugin which has a menu Cookie -> show cookie information. There you should see a PHPSESSID cookie (after login). If not, your URL should include some information about the session id (looks like this: ?PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4). Otherwise, PHP cannot find a session, because it does not know which session belongs to you.

If this does not help check if the cookie is set:

  • Again open your header plugin and then perform a login. Check if the server sends a cookie to you. This must be done in a Set-Cookie command. It might look like this: Set-Cookie: PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4; path=/
  • If the server does not set a cookie, check for the settings in php.ini. There must be a setting session.use_cookies = 1 which must be set to 1 or On to allow PHP to use cookies.
  • If the server does set a cookie, but your browser does not allow it, check the options of your browser for cookies. Also check the php.ini setting for session.use_only_cookies = 0. If this is set to 1 you forbid PHP to use the URL if a cookie is not accepted by the browser. This is usually forbidden for security reasons, because people copy URLs to friends and then these friends will take over the logged in session ;) So just set it to 0 for debugging purposes.
  • var_dump() the return value of session_start(). It will return false if PHP was not able to start the session correctly.
like image 138
aufziehvogel Avatar answered Oct 23 '22 18:10

aufziehvogel


Mystery solved here: Byte Order Mark

enter image description here

Best answer you will find:

https://stackoverflow.com/a/8028987/424004

like image 34
Dejan Marjanović Avatar answered Oct 23 '22 18:10

Dejan Marjanović


Try printing the PHPSESSID with session_id(). Do you get the same output if you keep refreshing?

If not try to set the id with: session_id('cutckilc16fm3h66k1amrrls96')

http://php.net/manual/en/function.session-id.php

It should work now, but with the same session for all users.

The problem could be something like this: PHP Session data not being saved

like image 1
EmilF Avatar answered Oct 23 '22 18:10

EmilF