Reputation: 4200
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"; ?>
.
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();
?>
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'])
.
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:
Any advice will be appreciated.
To make it clear what happens (and what doesn't happen) I have put in some echo
s at different spots. This snippet of the above code with some additional echo
s:
...
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.
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...
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.
Upvotes: 6
Views: 9059
Reputation: 19380
Mystery solved here: Byte Order Mark
Best answer you will find:
https://stackoverflow.com/a/8028987/424004
Upvotes: 2
Reputation: 4200
After many long days and nights of testing, reading and asking and with a lot of help from the participants on this question - thanks a lot for your effort! - I slowly reached this rather mysterious solution to the problem.
A solution I found, but an explanation I still don't have...
So, as described in Update 2, I found from the answer from @EmilF that the session id changed constantly. A thought was then to suspect a server / host issue. I contacted the host - one.com - who at first like me didn't understand, why it didn't work.
But then he told me, there was some rather odd symbols in the beginning of the check.php
file. I couldn't see them in my own editor. They weren't visible until I accessed the file via the FileManager software that one.com provides browser based.
The top of the file looked like this:
<?
ob_start();
session_start();
if($_POST['password'] == 'xxx') { // Correct password
$_SESSION['login'] = true;
...
You can see the odd symbols 
in the beginning. As I said, they were not visible in my own editor Notepad++, nor in regular Notepad. I sent the file to a friend to check, and he couldn't see them either in his editor, Coda.
These symbols would of course act as output to the browser. Therefor this is a request to the browser that occours before the session_start()
and the header(Location:...
. Because those two commands must be prior to any browser request, they don't work now in this case with the symbols present.
Sessions and header
command work perfect now with the symbols removed.
I have no idea why they are there, but after more testing I found out how they got there:
In Notepad++ I can change the coding format in the menu. When I change from fx ANSI to UTF-8, the symbols have appeared. In normal Notepad I can save as UTF-8 as an option in the "Save as" window. And the symbols also appear in this case.
In any case I can only see the symbols 
, when I view the code through a browser based editor that takes the files directly from the server. And nomatter the editor it is always 
that are created.
I don't have the explanation for this. This might be a good topic for another SO question.
Thanks to all who tried to help me. I am answering the question here, because this is the answer. But all help and debugging tricks have been much appreciated and very helpful.
Thanks a lot and have a good summer all of you.
Upvotes: 0
Reputation: 109
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
Upvotes: 1
Reputation: 7297
Okey, let’s list everything you can debug here, mentioning also stuff you already did (so other people can read it):
Location:
header is sent to your browser or not.error_reporting(E_ALL);
?var_dump()
for the $_POST
array.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:
Set-Cookie
command. It might look like this: Set-Cookie: PHPSESSID=514515ca274866b9f0b5b2520b6fcbb4; path=/
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.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.Upvotes: 3