Really annoying problem I can't solve/can only partially solve. Nice juicy one for you pros.
I've got a basic login system set up. Like this:
Login.php:
line 1: session_start();
Check if($_SESSION['logged_in'] == true) header("Location: /controls.php);, incase they've already entered their details.
If they haven't entered them yet, user enters credentials, if valid: $_SESSION['logged_in'] = true;
After database credentials are checked and session is set to true, redirect using PHP header("Location: /controls.php);
Bear in mind, the session is now set.
Controls.php
line 1: session_start();
line 2: if($_SESSION['logged_in'] != true) {header("Location: /index.php");}
Instantly I get taken to index.php ONLY IN CHROME AND FIREFOX.
Also, I have accounttools.php, where the session is again required. Once I try to access accounttools.php, the session is destroyed/unset and any attempt to load accounttools.php results in the header redirect to my /index.php page, again ONLY IN FIREFOX AND CHROME.
I've also got to add in something. If I go back to login.php and re-login, everything works fine and the session gets set properly. Is this a browser-based bug? PHP is executed before any data gets sent to the browser, so how on earth can these browsers act differently if the PHP has already been executed by the time anything reaches the user?
Login file:
// Login.php
<?php session_start();
if($_SESSION['logged_in'] == true)
{
header("Location: /controls.php");
exit();
}
if($_POST['username_login'] && $_POST['password_login'])
{
// Do necessary database work to check credentials (edited out here).
// ...
// Check re-hashed pass against database hash (password checking)
if($make_password == $current_user[0]['password'])
{
// If this is OK login is a success.
$_SESSION['logged_in'] = true;
header("Location: /controls.php");
exit();
}
}
?>
Controls file:
// controls.php
// This page instantly redirects to index.php
<?php session_start();
// Go to homepage if logging out.
if($_POST['logging_out'])
{
unset($_SESSION['logged_in']);
header("Location: /index.php");
exit();
}
// No access unless logged in.
// This session seems to no longer exist at this point. Why??
if($_SESSION['logged_in'] != true)
{
header("Location: /index.php");
exit();
}
?>
Edit: I've discovered something else: If I login and manually enter the URL of the $_SESSION-restricted page, the $_SESSION is not destroyed.
There is some part of the header() redirect that is causing th $_SESSION to become unset/destroyed in Google and Mozilla.
I've also been Googling like crazy and apparently this is a common problem amongs PHP coders. Someone must have a clue what this is?
I see a problem with the way you are redirecting after a successful login: It is a javascript redirect so it will only happen after all the php has finished executing and the result has been sent to the browser. That means that codes after your redirect are executed as well.
I would recommend not outputting anything to the browser until the very end and use the:
header("Location: /...");
exit();
combination everywhere where you want to redirect so that you are sure that nothing happens to your session after the redirect code.
To avoid getting headers already sent problems, I would also recommend getting rid of stuff like:
?>
<?php
like on the first lines of login.php.
Related
I have a page, login.php, that processes a username and password and if successful it sets session variables and then redirects the user to home.php. The relevant part of login.php is here:
if ($pwdHash == $storedpass) {
$success = true;
$sessionStatus = session_status();
if ($sessionStatus !== PHP_SESSION_ACTIVE) {
session_start();
}
$_SESSION['user_id'] = $user;
$_SESSION['logged_in'] = true;
session_write_close();
header('Location: http://www.examplesite.com/home.php');
header("HTTP/1.1 303 See Other");
die("redirecting");
}
Then home.php tries to collect the session variable
$sessionStatus = session_status();
if ($sessionStatus !== PHP_SESSION_ACTIVE) {
session_start();
}
$loggedIn = $_SESSION['logged_in'];
The problem is that on the first login attempt, $_SESSION['logged_in'] is undefined and generates an error, even though login.php was successful.
Notice: Undefined index: logged_in
A var_dump of $_SESSION returns an empty array, but sessionStatus reports that the session was already started, it did not have to execute session_start.
This forces the user to log in a second time, then everything is fine. So is the redirect just happening too fast for the session variable to get set? Should I put a delay in the redirect? (and how would I do that?) Or is this something else that I'm doing wrong?
EDIT: I've checked with my host based on an answer to a similar question and confirmed that a session would never be served by more than one server and there is no need to enable sticky sessions or anything like that. I've also updated the code above based an answer offered below and some other research but the error persists.
The session is probably automatically saved when the script ends. You redirect before the script ends.
How long your script takes to really end depends very much on what other code needs to wind down. It is better to explicitly save the session.
How to do this depends on what kind of sessions you use. One type can be closed like this:
http://php.net/manual/en/function.session-write-close.php
If that's the one you're using do this:
if ($pwdHash == $storedpass) {
$success = true;
$_SESSION['user_id'] = $user;
$_SESSION['logged_in'] = true;
session_write_close();
header('Location: http://www.examplesite.com/home.php');
header("HTTP/1.1 303 See Other");
die("redirecting");
}
And the session should be available to the next page when you redirect.
If your sessions work differently, you have to adapt the code, of course. The point I'm trying to make is: Never put a delay in your code. It's unreliable, and pointless. Simply save the session before you redirect.
I have experienced the same issue while writing the session content to the database.
To make it work I have added the sleep() function before setting the session variable, just like below.
sleep(2);
$_SESSION['GUID'] = uniqid(time().rand());
It resolves the issue for me.
We have observed this issue when the page hits are frequent but if one or two users are accessing the page it works as expected.
I have encountered this same issue with a login page but none of the suggestions work for me. The only thing I've found that does work is redirecting the page to itself after 1 second and then checking the session variables to see if the login was successful...
startSession(); // assigns all the login session variables, etc.
header('Refresh: 1; URL=/[THIS_PAGE].php'); // [THIS_PAGE] = the current login page
However, this is a very inelegant solution and I don't like using it. But it "works".
This problem persists. In my case, the user login goes without a problem to the protected homepage, but clicking on a menu link causes the user to be dumped back to the login page to login again. A check on certain Session values (required for both pages) shows these are not set on going to the specific menu link (while other menu links cause no problem). The code requiring a session value is the same in all cases. Not all users experience the problem. Seems that those with less robust connections to the internet always experience this problem. Others, never.
Found a major problem on my website. I found tha if I login with user A. it sometimes kinda does log in but actually doesn't. Then I login with user B -> enter the site. I log out and then go manually back to url where login is needed and it somehow goes in with user A. It seems that I have two (maybe could have more) session_id cookies on different tabs or there is a ghost session_id that comes active I don't know. Pulling my hairs here.
Also found that, lets say I have a user dashboard and test page. With a little going back and forth with different credentials. I get this result:
Dashboard echoes user A's id, test echoes user B's id or not id at all. What the heck I am doing wrong with my sessions?
Login is done with AJAX. Login validation is the same on every page.
COMMON FUNCTIONS:
function validateUser($userid) {
session_regenerate_id();
$_SESSION['valid'] = 1;
$_SESSION['usersid'] = $userid;
}
function isLoggedIn() {
if (isset($_SESSION['valid']) && $_SESSION['valid'] == 1) {
return true;
} else {
return false;
}
}
function logout() {
$_SESSION = array();
session_unset();
session_destroy();
}
LOGIN/DB:
Login page:
session_start();
include 'include_files.php';
if(isLoggedIn()){
header('Location:loginrequiredpage.php');
die();
}
Login page sends username/password with AJAX to an controller php file that uses db functions as included file. It executes usercheckfunc() which checks user from db and then echoes succes or fail back to ajax.
from db functions - part of user check function
//if user found from db and password hash match
validateUser(**ID FROM DATABASE**);
Back in login page if ajax gets success message back, JS send user to login required url.
Here's where mystery sometimes occur The browser acts like if i just logged in somewhere, but the login page is loaded again. Sometimes I can manually go to login required page via address bar. Sometimes if I logout/idle too long etc. and login with different username/password I get in as a wrong user. Entered as user A, See user B's data OR echo different userids on pages or echo id only on other page.
LOGIN REQUIRED PAGE:
<?php
session_start();
require_once 'include_files.php';
if (!isLoggedIn()) {
logout();
header('Location:login.php');
die();
}
echo $_SESSION['usersid'];
Test page:
<?php
session_start();
error_reporting(E_ALL);
ini_set('display_errors', 1);
require_once 'include_files.php';
if (!isLoggedIn()) {
logout();
header('Location:login.php');
die();
}
echo $_SESSION['usersid'];
Is there a "best" way to manage sessions? Help is much appreciated :)
Got rid of the problem by manually setting session cookie parameters everywhere before session_start is executed. Now the session cookie domain doesn't behave unexpectedly. Sorry, no idea why it did that mysterious changeing before.
This cookie parameters sets it to be valid on whole domain. I guess it's no good in situation where you need different sessions on the same domain (different applications etc.). But for me it was the healing patch I needed.
session_set_cookie_params(0, '/', '.example.com');
session_start();
I am trying to verify that a user has logged in before showing them the page, using the method below, while the if/else method works when wrapped around plain html, it is failing when there is php involved. I am a novice by the way. What happens is the page simply loads as if the two tags below weren't there...which would be fine had I previously logged in, but I hadn't.
<?php
session_start();
if(isset($_SESSION['user'])) {
?>
HTML/PHP Page goes here.
<?php
} else {
header("Location: cms/admin/loginreadmode.php");
}
?>
Thanks in advance,
You can debug just below your session_start(); by printing your session:
echo '<pre>';
print_r($_SESSION);
die();
If $_SESSION['user'] isn't showing up in your array it isn't be set.
You can do this like this:
session_start();
$_SESSION['user'] = true;
Are you sure that you have add session support in every page?
if (!isset($_SESSION)) {
session_start();
}
This code should be working, so mistake is probably somwhere else I suggest checking if you set $_session["user] after login.
You should also replace your not-working code part with simple
echo "hello";
to chek it.
1) That is not a great method of checking whether a user is logged in, purely checking whether a user sessions exists can end up causing a lot of problems. Storing the ID in the sessions and then checking whether the ID is valid may be a better way,
2) When I copy the code above into a test document it goes straight to the redirect page in the else statement. This is down to the user session not being set, as soon as I set the user session before the code is executed it works fine. I see 'HTML/PHP Page goes here.'.
Setting the user session:
$_SESSION['user'] = 'TestUser';
You can change the code at the top of the page to be
<?php
session_start();
if(!isset($_SESSION['user'])) {
header("Location: cms/admin/loginreadmode.php");
die();
}
?>
I created a login page in php named as index.php. Now when the user logs in it redirects to mypage.php. The login works fine. But also mypage.php gets open when I type the url of mypage.php even without login. I want the user must logged in to see mypage.php and incase if he changes the url in browser then an error message should be triggered. What to do?
1.localhost/index.php
2.localhost/mypage.php
In index.php, once the user gets logged in successfully, set an session. like $_SESSION['login'] = true; before redirect. If invalid login, use $_SESSION['login'] = false; Don't forget to start the session on the top of the page. session_start();
In mypage.php, check if that session is set or not. If not set, throw error, else show the page.
session_start();
if(isset($_SESSION['login']) && $_SESSION['login'] == true) {
echo 'You are welcome';
} else {
echo 'redirecting to login page';
header('Location: index.php');
exit;
}
How are you storing the state of being 'logged in'?
You'll need to have your mypage.php check a variable that has been set by the index.php's successful login process.
Can you paste your code here and I can take a look
In order for a login to work correctly, your "secure" page (I use that term relatively because nothing is truly secure) needs to have some sort of validation conditional. In other words you need to have some way of determining if the user is logged in.
A simple way to do this in PHP is to set a session variable when you process the user's credentials. For example:
When the user successfully logs in set a session variable like so:
$_SESSION['isLoggedIn'] = true;
Then on the mypage.php check to see if the variable is set:
if(!isset($_SESSION['isLoggedIn']) || $_SESSION['isLoggedIn'] != true) {
header("Location: index.php");
exit;
}
Please also note, it is imperative if you are using sessions that you have session_start(); as the first line of all of your files. This allows $_SESSION variables that were set on a separate page to be able to be read on the current page.
Hope this helps.
1: i use register.php to sign up the clients,
2: the data collected from the form is send to 1.php, it is saved in database
3: after form data is saved in database, 1.php forwards selected form data (myValue) to register.php?myValue='abc'
in 1.php, i am saving a session variable like this
#session_start();
$_SESSION['color']='blue';
the code of register.php is
if (isset($_SESSION['color'])) {
header('Location: http://mydomain.com/thankyou.php');
}
else {
#session_start();
some other stuff that was initially use for signing up the clients
my logic is to check for session variable and to redirect it to some-other page
when step 1 , step 2 and step 3 are complete, page should be
redirected to thankyou.php
currently, when step 1, step 2, step 3 are done, instead of opening thankyou.php, the following page is being opened
http://mydomain.com/register.php?myValue='abc'
however, if i re-open register.php or go back to step one (opening register.php), thankyou.php is displayed...
can somebody guide me where i am doing the blunder? why redirection is not being successful although session variables are being created?
code Update
i tried the following code at the top of my register.php
#session_start();
if (isset($_SESSION['color'])) {
header('Location:http://mydomain.com/thankyou.php');
exit;
}
else{
remaining stuff
it occasionally do the trick, redirects to the page, while on occasion (greater in number), it fails in redirecting to thankyou.php,, also the code needs to delete complete history and cache to work (after doing so, still miss hits occurs..)
Make sure you use exit(0); right after you do a header redirect otherwise php will still parse and run the rest of your script, sometimes it can cause some funny behaviour.
In your register.php, you can't test for the session variable before you issue the session_start, so your code should be more like:
session_start();
if (isset($_SESSION['color'])) {
header('Location: http://mydomain.com/thankyou.php');
}
else {
// Something else....
EDIT:
Another thing I've found useful when trying to set session variable in conjunction with redirects is to proceed to the redirect only after running a function. Here's how it would work:
$throwAwayVariable = setColor('blue');
if($throwAwayVariable ){ // separated out into a function so it wouldn't redirect before the session variable was saved
session_write_close();
header("Location: http://mydomain.com/thankyou.php");
}
function setColor($color){
#session_start();
$_SESSION['color']='blue';
return true;
}
Since not all your code is posted, you'll have to figure out where this goes, but I've always had my session vars work after this process.
Your session_start() call in register.php needs to be BEFORE you call any $_SESSION variables.
I have the same issue, then I try to add session_start and session_write_close, and it works!
session_start();
$_SESSION['status'] = 'Updated Poem successfully';
session_write_close();
header("location: index.php");