user3900117
user3900117

Reputation:

PHP Sessions echos every username

I'm new to PHP and just read an entire book on it. I'm attempting my first real log in on my own. I set up my database and the user logs in with email and password. Each user has a iduser and a username. Using sessions, how can I make it where only the username of the user logged in is echoed on the profile.php? Right now it doesn't matter which user I log in with every username is echoed on profile.php. The log in code works fine, just need help with the sessions with echoing the right username.

My Code:

home.php

<!DOCTYPE html>
<?php
include "header.php";
session_start();
session_destroy();
$_SESSION = array();
?>

<html>
<!--home page center login box-->
<div id="homebox1">
    <div id="logohome">
        <h2>Welcome</h2></br>
    </div>
    <div id="homecolumn1">
        <p>Login</p></br>
        <form id="login" action="login.php" method="post">
            <input name="emaillogin" placeholder="email" type="email" rows="20"> </input></br>
            <input name="passwordlogin" placeholder="password" type="password" rows="20"> </input></br>
            <input type="submit" value="Log In"> </input>
        </form>
    </div>
</div>
<!--footer1.php-->
</body>
</html>

login.php

<?php
include "connect.php";
include "header.php";
session_start();

$sql = "select * from profile where email='" . $_POST["emaillogin"] . "' and password='" . md5($_POST["passwordlogin"]) . "'";
$res = mysqli_query($con, $sql);
if(mysqli_num_rows($res) > 0) {
    header("location: profile.php");
}else if(mysqli_num_rows($res) <= 0) { 
    session_destroy();
    include "home.php ";
    echo "incorrect email or password";
}
?>
<?php
//include "disconnect.php";
?>

profile.php

<?php
include "connect.php";
$res = mysqli_query($con, "select * from profile");
$num = mysqli_num_rows($res);
while ($dsatz = mysqli_fetch_assoc($res)) {
    echo $dsatz["username"];
}
?>

Upvotes: 1

Views: 955

Answers (3)

Rasclatt
Rasclatt

Reputation: 12505

This is the main problem relating to why you get all your users showing in your profile:

profile.php

As suggested by J A you will want to do a specific search for the user based on session username or id ( or whatever you use to differentiate users in tables) otherwise you will return your entire user table (which in your case is probably not that big since you are starting out and just testing the waters, so-to-speak) but in a large table, that is a bad idea.

Secondary for this page: You will also still want to use binding in your sql statement to help prevent sql injection as you do in your login.php page (revised outlined below). As mentioned by PeeHaa, you will want to make sure you use some sort of sanitization when echoing user inputed data to the browser. This would include (but not limited to) something like htmlspecialchars(), htmlentities(), or strip_tags()...etc. Reason for this is if someone decides to write their name (or whatever else you allow for a user profile): <script>some.Malicious('nastyjsCode')</script> it will write it, as embedded HTML, to your page when you echo $_SESSION['name'].

Something like:

// Lets say this is what was assigned from your database that
// the user input as their name at the time of sign-up
$_SESSION['name'] = "<script>some.Malicious('nastyjsCode')</script>";

// When you fetch it from your database or grab it from session
// echo to page like so
echo "Welcome ".htmlentities($_SESSION['name'],ENT_QUOTES)."!";

Will actually produce in your source code:

Welcome &lt;script&gt;some.Malicious(&#039;nastyjsCode&#039;)&lt;/script&gt;!

But will display on the page (which is fine. It just means this user has a dumb name):

Welcome <script>some.Malicious('nastyjsCode')</script>!

As a summary from all comments:

home.php

<?php
// Just session start before everything
session_start(); ?>
<!DOCTYPE html>
<html>
<?php 
// I don't know what this has in it, so it may or may not work here
// Since you have a close <body> I presume it has an open tag and
// such in this header.php file?
include("header.php"); ?>
<!--home page center login box-->
<div id="homebox1">
    <div id="logohome">
        <h2>Welcome</h2></br>
    </div>
    <div id="homecolumn1">
        <p>Login</p></br>
        <form id="login" action="login.php" method="post">
            <input name="emaillogin" placeholder="email" type="email" rows="20"> </input></br>
            <input name="passwordlogin" placeholder="password" type="password" rows="20"> </input></br>
            <input type="submit" value="Log In"> </input>
        </form>
    </div>
</div>
<!--footer1.php-->
</body>
</html>

login.php

<?php
session_start();
include("connect.php");
// You may not need this here. Likely you can put this down in the fail portion
// of the login. I don't know what's in it though. If there is html contained in
// this file, it may disrupt your header() function in the success portion of
// your script (header already sent error/warning)
include("header.php");

// I use PDO, so I am not 100% familiar with the procedural version of this function,
// but according to the PHP manual, this is the step for binding mysqli for
// prevention of sql injection attacks
$res = mysqli_prepare($con, "select * from profile where email = ? and password = ?");
// As mentioned by PeeHaa, the md5() is not good enough to store passwords. You will
// need to do stronger encryption. If your version of PHP allows automated salted encryption,
// use that, if not, you will want to seek out a more manual way of salting/encrypting
mysqli_stmt_bind_param($res, $_POST["emaillogin"],md5($_POST["passwordlogin"]));
mysqli_stmt_execute($res);

// Specifically returning 1 row, not just greater than 0 as noted
// by Emilio Gort in OP comments
if(mysqli_num_rows($res) === 1) {
    // On success, fetch user data in an array
    $result = mysqli_fetch_assoc($res);
    // Assign single values or the entire data array as suggested by Mike
    $_SESSION['username'] = $result['username'];
    $_SESSION['email'] = $result['email'];
    // etc..
    header("location: profile.php");
    // It is common practice to add exit after a header()
    // so the script stops processing
    exit;
}
// you don't have to specify the less-than/equal-to here because it's either
// equal to 1 or not
else {
    // You may also want to consider redirecting back to home with a
    // $_GET error code instead of echoing html:

    // header('Location: home.php?err=login');

    // Then on the home.php have a spot near the form that has:
    // if(isset($_GET['err']) && $_GET['err'] == 'login')
    //     echo 'incorrect email or password';

    include("home.php");
    // I suspect this header file should go here instead of top
    // (if it contains html). If so, uncomment and remove from top
    //include("header.php");
    echo "incorrect email or password";
} 

//include "disconnect.php";
?>

Upvotes: 3

Mike
Mike

Reputation: 456

Easiest would be to add the user name (and any other user info that you interact with) to the $_SESSION array and then just call that rather than doing another sql query.

Eg in login.php

if(mysqli_num_rows($res) > 0) {
  $_SESSION['user']=mysqli_fetch_assoc($res);

and in profile.php you just echo $_SESSION['user']['username'];.

Upvotes: 0

J A
J A

Reputation: 1766

From a quick glance at the question, there seems to be two things missing.

1. Not saving the logged-in-user details in the session.: You would need to save the user details upon successful authentication.

if (mysqli_num_rows($res) > 0) {

    $result = mysqli_fetch_assoc($res);
    $_SESSION['userDetails'] = $result;

    header("location: profile.php"); 

2. In the profile page, Sql is not filtering the logged-in-user.: You can either save all details of logged in user in the session (like above) or you can just save the primary field (user-id) and use it as a filter in all of your later queries.

$res = mysqli_query($con, "select * from profile WHERE user-id = $_SESSION['userId] LIMIT 1");

Upvotes: 0

Related Questions