0

i am developing a log in form with session. When i log in and try to change page in the same domain and get back to login page, i am logged out and credentials needed. Bellow is the code.

mysky.php (login page)

<?php   
    session_start();
    $pageTitle = 'MySky Login';
    include 'header.php';
?>


<div id="cloud_box">
    <div id="cloud_title">My<span>Sky</span> Login</div>

    <form action="myskyweb.php" name="form" method="POST" 
     onsubmit="return IsEmpty();">

        <div id="msg"><?php if(isset($msg)) { echo $msg; }?></div>

        <div id="u">
            <div id="user1">U</div>
            <input type="text" id="user" name="user"/>
            <div id="error_u"></div>
        </div>

        <div id="p">
            <div id="pass1">P</div>
            <input type="password" id="pass" name="pass"/>
            <div id="error_p"></div>
        </div>

        <button id="btn" type="submit">Login</button>

    </form>

</div>



<?php include 'footer.php';?>

myskyweb.php (after successfull login)

<?php 
    session_start();
    if(!isset($_SESSION['id']))
    {
        header("Location: mysky.php");
    }
    $pageTitle = sprintf('MySky - %s', $_POST['user']);
    include 'header.php';
    include 'login.php';
?>

<?php

print_r($_SESSION);

?>

<div id="logout"><a href="logout.php">Logout</a></div>

<?php include 'footer.php';?>

page1.php (one page of my domain)

<?php 
    session_start();
    $pageTitle = 'page1';
    include 'header.php';
?>

<?php

print_r($_SESSION);

?>

<div id="structure">

<?php include 'footer.php';?>

page2.php (another page)

<?php 
    session_start();
    $pageTitle = 'page2';
    include 'header.php';
?>

<?php

print_r($_SESSION);

?>

<div class="slides">

<?php include 'footer.php';?>

login.php (checking if credentials are correct & give value to session)

<?php

    include 'db_info.php';      
    $username = $password = $encrypted = $msg = '';

    //connect to db
    $conn = new mysqli($dbServer, $dbUser, $dbPass, $dbName) 
    or die($conn);

    //get values
    $username = $_POST['user'];
    $password = $_POST['pass'];

    //prevent mysql injection
    $username = stripcslashes($username);
    $password = stripcslashes($password);
    $username = mysqli_real_escape_string($conn, $username);
    $password = mysqli_real_escape_string($conn, $password);

    //encrypt pass
    $encrypted = md5($password);

    //search
    $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$encrypted'";
    $result = mysqli_query($conn, $sql) or die("Failed to query database ".mysqli_error($conn));

    //compare
    $row = mysqli_fetch_array($result);
    if (($row['username'] == $username) && ($row['password'] == $encrypted)){
        $_SESSION['id'] = $row['id'];
        $_SESSION['user'] = $row['username'];
        $_SESSION['logged_in'] = time();
    } else {
        $msg = 'Credentials mismatch';
        header("Location: /mysky.php");
        die();
    }
    mysqli_close($conn);


?>

I used the function print_r() at all of the pages to understand if the problem is the session. Session is not the problem, because after log in every page shows the sessions var. So session keep the values after changing a page. I cannot undestand why i see login form in login page again rather to see successfull login page.

Any help is appreciated!

ntinos2o
  • 1
  • 1
  • 4
  • Please show us the output of `print_r($_SESSION);`. Does it have an `id` element? – waterloomatt Aug 14 '18 at 15:06
  • A couple of things. 1.) You're not actually validating the username/pwd. 2.) when the log in form is submitted to `myskyweb.php`, you are checking for a session variable called `id`. If it is not set (and it won't magically be set) then you are redirecting back to the log in page. This is your issue. You need to validate the username/pwd and then set a session variable. You would then check for that session variable in all of your pages. If it is not set, then the user is not validated and you should redirect. – waterloomatt Aug 14 '18 at 15:10
  • The output of print_r($_SESSION) : Array ( [id] => 1 [user] => admin [logged_in] => 1534259808 ) . Its has the values of the database. So session works fine, right? – ntinos2o Aug 14 '18 at 15:19
  • I have posted login.php above with credentials check and session var given. I think it is correct, but take a look! – ntinos2o Aug 14 '18 at 15:26
  • Ahh, I see now. You need to `include 'login.php';` right after starting the session in _myskyweb.php_. Currently, you're only including it after doing the check for `isset($_SESSION['id'])`. – waterloomatt Aug 14 '18 at 15:34
  • I tried it and when i logged in it shows **Notice: session_start(): A session had already been started**, because in **myskyweb.php** i call session_start() before **include 'login.php';**. – ntinos2o Aug 14 '18 at 15:37
  • Updated my comment. You should also call `die;` after issuing a `header` call - https://stackoverflow.com/a/768472/296555 – waterloomatt Aug 14 '18 at 15:40
  • I can successful login but if then click to menu **page1.php** and then click to **mysky.php**, i see the login form again and not the myskyweb.php (authorized page) – ntinos2o Aug 14 '18 at 15:59

3 Answers3

0

You'll need to assign a $_SESSION variable when they are logged in. Take a look at my example below

Login.php

//login code

.....

//
//if successful
            $_SESSION['user_id'] = $user['username'];
        $_SESSION['logged_in'] = time();

        header( "Location: /protected.php" );
        die();

And then at the top of your subsequent pages for example..

home.php

<?php 
session_start();
if(isset($_SESSION['user_id']) || isset($_SESSION['logged in'])){ 
echo 'blah'
?>

if you want to remove the login button or redirect if they try to access the login page you'd need to do some handling to implement this.

Change login button -> logout button

<?php if(isset($_SESSION['user_id']) || isset($_SESSION['logged in'])){ 
?>
            <li> <a href="logout.php"> Logout | <?php echo 
$_SESSION['user_id'] ?> </a></li>
            <?php }else{ ?>
            <li> <a href="loginpage.php" >login</a></li>
                <?php } ?>

Protected.php

<?php


session_start();
if(!isset($_SESSION['user_id']) || !isset($_SESSION['logged_in'])){

echo "Oops, you're not supposed to be here\n";
echo 'You\'ll be redirected in  5 seconds. If not, click <a 
href="index.php">here</a>.';
header( "refresh:5;url=index.php" );
exit;
}


echo 'Congratulations! You are logged in!';
echo 'You\'ll be redirected in  5 seconds. If not, click <a 
href="index.php">here</a>.';
header( "refresh:5;url=index.php" );
die();


?>

I believe this is everything you want to achieve, just change variables as required

Isaac
  • 784
  • 10
  • 23
  • thanks for responding! If i write **header( "Location: /home.php" );** in the login.php after successfull credentials check, the form does not submit for some reason. I posted the login.php above, please take a look. Thanks! – ntinos2o Aug 14 '18 at 15:30
  • Ammed your code in login so it has the capital L and the / before the file name – Isaac Aug 14 '18 at 15:39
  • You mean after the **else**? This won't change the login issue i think.. right? – ntinos2o Aug 14 '18 at 15:45
  • So it works if you don't redirect? are you getting any errors? try to add die(); after the redirect – Isaac Aug 14 '18 at 15:46
  • if i redirect to **myskyweb.php** (this is the page i want to see the user after log in), redirect does not work. If i redirect to another page, redirect works. If i dont use redirect there, with the **
    – ntinos2o Aug 14 '18 at 15:52
  • I added a section called protected.php. When they login, redirect them to that page. Then it should work – Isaac Aug 14 '18 at 16:46
  • I took this error message from browser **The page isn’t redirecting properly** – ntinos2o Aug 14 '18 at 16:59
0

EDIT 1

I can successful login but if then click to menu page1.php and then click to mysky.php, i see the login form again and not the myskyweb.php (authorized page)

OK - this is important. So your issue is not logging in, right? But, after authenticating, if you go back to log in page, you see the login form and you are not redirected. You want to automatically be redirected to the landing page if you are already authenticated. Is that right?

If so, then my question is, where in mysky.php (login page) are you checking if the user is logged in? I don't see that check anywhere.

You need to:

<?php

session_start();

// If the user is already logged in, redirect them to the landing page. 
if (isset($_SESSION['id'])) {
    header("Location: myskyweb.php");
} 

You are only calling login.php after checking if the session variable id is set. That is why it is redirecting you back to the login page. Move that include up, directly under session_start(). The only reason that it sometimes works is that there is an existing session - see my next point.

myskyweb.php (after successfull login)

<?php 
session_start();

// Move this include up here before the check.
include 'login.php';

if(!isset($_SESSION['id']))
{
    header("Location: mysky.php");
}
$pageTitle = sprintf('MySky - %s', $_POST['user']);
include 'header.php';
...
?>

Also, for debugging purposes, clear the session each time you hit the log in screen. That way you'll not be confused about stale session data keeping you logged in

mysky.php (login page)

<?php

// Always clear the session when hitting the log in page. 
session_destroy();
$_SESSION = [];
...

You're wide open to SQL Injection attacks - look up parameterized queries.

You need to call die; after issuing a header call - https://stackoverflow.com/a/768472/296555

waterloomatt
  • 3,662
  • 1
  • 19
  • 25
  • Include has to be at the top – Isaac Aug 14 '18 at 16:29
  • I tried moving the **include 'login.php';** before the check but nothing changed. Now i am in **mysky.php** and i see the login form and the output of **print_r($_SESSION);**. Session array has got the variables id and user (so i am logged in) and i am stil watching the log in form rather seeing the logged in page (myskyweb.php). Any ideas? – ntinos2o Aug 14 '18 at 16:40
  • See my 2nd point, clear your current session, and reload the login page. – waterloomatt Aug 14 '18 at 17:27
  • Where exactly call the function in the log in page? at the top? before session start? after? – ntinos2o Aug 14 '18 at 18:39
  • Do it right at the top; directly after opening ` – waterloomatt Aug 14 '18 at 18:46
0

@waterloomatt & @Isaac thanks for your time and responses! After so many hours, finally i found the code that works. If you see anything wrong, i would be happy to know! Will i have problems with SQL Injection attacks?

login.php

<?php
    session_start();

    include 'db_info.php';  

    //connect to db
    $conn = new mysqli($dbServer, $dbUser, $dbPass, $dbName) 
    or die($conn);

    //get values
    if ((isset($_POST['user'])) && (isset($_POST['user']))){
        $username = $_POST['user'];
        $password = $_POST['pass'];
    } else {
        $username = null;
        $password = null;
    }   

    //prevent mysql injection
    $username = stripcslashes($username);
    $password = stripcslashes($password);
    $username = mysqli_real_escape_string($conn, $username);
    $password = mysqli_real_escape_string($conn, $password);

    //encrypt pass
    $encrypted = hash('sha256', $password);

    //search
    $sql = "SELECT * FROM users WHERE username = '$username' AND password = '$encrypted'";
    $result = mysqli_query($conn, $sql) or die("Failed to query database ".mysqli_error($conn));

    //compare
    $row = mysqli_fetch_array($result);
    if (($row['username'] != $username) || ($row['password'] != $encrypted)){
        if ((isset($_POST['user'])) && (isset($_POST['pass']))){
        $_SESSION['msg'] = 'Credentials mismatch';}
    } else {
        $_SESSION['id'] = $row['id'];
        $_SESSION['user'] = $row['username'];
    }
    mysqli_close($conn);


?>

mysky.php

<?php 
    include 'login.php';

    if ((isset($_SESSION['id'])) && (isset($_SESSION['user'])))
    {
        include 'sky_auth.php';
    } 
    else
    {
        include 'sky_login.php';
    }

    include 'footer.php';
?>

sky_login.php

<?php 
    $pageTitle = 'MySky Login';
    include 'header.php';
?>


<div id="cloud_box">
    <div id="cloud_title">My<span>Sky</span> Login</div>

    <form action="" name="form" method="POST" onsubmit="return IsEmpty();">

        <div id="msg"><?php if (isset($_SESSION['msg'])){
                                echo $_SESSION['msg']; 
                                unset($_SESSION); 
                                session_destroy();} ?>
        </div>

        <div id="u">
            <div id="user1">U</div>
            <input type="text" id="user" name="user"/>
            <div id="error_u"></div>
        </div>

        <div id="p">
            <div id="pass1">P</div>
            <input type="password" id="pass" name="pass"/>
            <div id="error_p"></div>
        </div>

        <button id="btn" type="submit">Login</button>

    </form>

</div>

sky_auth.php

<?php
    if(!isset($_SESSION['id']))
    {
        header("Location: mysky.php");
        die();
    }
    $pageTitle = sprintf('MySky - %s', $_SESSION['user']);
    include 'header.php';
?>

<div id="sky_contain">

        <div id="logout"><a href="logout.php">Logout</a></div>

    </div>

</div>
ntinos2o
  • 1
  • 1
  • 4
  • Glad you got it going. Yes, you are still vulnerable to SQL injection attacks. The basic rule is to never include variables in your statements like so, `SELECT * FROM users WHERE username = '$username'...`. You should be using placeholders and prepared statements. See here - https://stackoverflow.com/q/60174/296555 – waterloomatt Aug 15 '18 at 12:13
  • Just saw this! glad you got it going! I'd also say use `Bcrypt` instead of SHA. SHA whilst secure are fast hashes. BCRYPT is a bit more secure imo – Isaac Aug 16 '18 at 17:31