mysql and php - Retrieving data from database based on user logged in - php

before I go ahead and attempt to create a website, I wanted to know if pulling a users content from a database depending on which user is logged in can be determined by a $_SESSION variable. So for example if I want all the messages for user 'example':
$_SESSION['username'] = $_POST['username'] // set when the user logs in
$username = $_SESSION['username']
$data = mysql_query("Select * from messagesTable where username = '$username'")
while($row = mysql_fetch_array($data)) {
echo $row['message']
}
I wanted to know if this would be the right way to do something like this and also if its safe to return (personal) data based on a session variable.
I haven't got that much experience in either of these languages but I like to learn with experience, please tell me if it's not clear. Thanks.

It is safe to return user data based on a $_SESSION variable if you are certain of its validity because you set it yourself in code. It is not safe to return data based on a session variable that you get from $_POST.
You initially set
$_SESSION['username'] = $_POST['username'];
So unless you have verified with a password or otherwise that this user is who he claims to be, you should not use $_POST['username'] to return other information. If your login process (which we cannot see above) already verifies that $_POST['username'] is valid, you can use it as a source to retrieve additional information.
You will need also to filter against SQL injection:
$_SESSION['username'] = mysql_real_escape_string($_POST['username']);

that isn't standard and probably not safe since phpsession stay open even when a browser tab maybe not be open to the site since the cookie isn't eased until the browser is shutdown and also you could just send a post parameter to the site and get the info too so login scripts are a little more advanced, you could something like have a unique key that is generate upon logging in and when they leave the site using javascript delete the cookie something like that

It wouldnt be the correct way to do it no.
May i suggest you go read the php/mysql docs and or a good book before attempting a website.
You also need to look into security(session hijacking, cross scripting, mysql attacks, form tokens, login systems, user roles/permissions). Google search is your friend...

<?php
session_start();
$username="";
if($_SESSION['username']==true){
$username=$_SESSION['username'];
$conn=mysql_connect('localhost','user','passwd') or die("Unable
to connect to database" .mysql_error());
mysql_select_db('DBName') or die(mysql_error());
$sql="SELECT * FROM tablename WHERE username='$username'";
$retval=mysql_query($sql, $conn) or die("Could not perform query"
.mysql_error());
while($row=mysql_fetch_array($retval)){
echo {$row['message']};
}
mysql_free_result($retval);
mysql_close($conn);
}
else{
return false;
header("Location:login.php");
}
?>

Related

Don't understand why $_SESSION is needed

I tried to create a login form from an example. I made it works but I don't understand.
Why $_SESSION['umsco'] is required and why should I assign the $username variable to it. I also do not understand if conn->close() required and what is the $result variable.
// I include the database file so we can get the information from there and apply it in here as well.
include "dbc.php";
// here we select the variables we want from the table 'members'.
$sql = "SELECT id, firstName, lastName FROM members";
// here we do something that I dont really know but this is standard procedure.
$result = mysqli_query($conn, $sql);
// declaring username
$username = $_POST["username"];
$password = $_POST["password"];
// my result thing, again, standard procedure.
$result = $conn->query($sql);
// we insert all values in row, standard procedure.
$row = $result->fetch_assoc();
// here we check if the username is the same as the database.
if ($username == $row["firstName"]) {
// if it's correct then we start a session
session_start();
// we give a session some random letters or numbers and set it to $username, not exactly sure why, but it wont work without it.
$_SESSION['umsco'] = $username;
// we change the location to secrect.php
header("location: secret.php");
}
// we close the connection, not sure if this is needed, but it seems logical.
$conn->close();
I advise you to always implement session_start()at the beginning of your code to avoid bad behavior.
What is a session
To understand, you must understand what a PHP session is.
A session is a way to keep variables on all pages of your site for a current user.
How it work
First you must ask PHP to initialize the session. For doing this, you must add session_start() at the beginning of your code.
When the server responds to the client, it append a cookie called PHPSESSID who contains the unique session identifier of the user.
At every request, the browser sends this cookie to the server so that php can recover the session from the hard disk of the server.
The most commun way to register a session variable is $_SESSION['key'] = $value;.
Final answer
To end, the line $_SESSION['umsco'] = $username; store the username of the user in his session until.
the session is destroyed with session_destroy()
the session expire after a time defined in php.ini
you unregister the variable.
In secret.php you probably check whether this value is assigned or if the session exists to check if the user is logged in. That's why it's mandatory, otherwise a login form would have no meaning.
Another ressource : Is closing the mysql connection important?
The result thing is that next time you call
session_start();
$loggedUserName = $_SESSION['umsco'];
you will have that user (username) available for you wherever you need it.
Just read basics of SESSION and you should be able to understand that.
Firstly, you need to query members where username and password match $_POST data.
Secondly, whatever is stored in $_SESSION variable will be available between requests. Typically, you want to "remember" user ID or similar so you do not need to submit username/password and repeat the member lookup with every request.
See more elaborate description here: https://www.johnmorrisonline.com/build-php-login-form-using-sessions/
What others have said about the $_SESSION variable is correct. If using session_start(); those values can be persisted across multiple requests from the users browser. The $_SESSION value will be particular to the user visiting your site.
Regarding the $result object, $result->fetch_assoc(); will only fetch one row from your table. So your current code would only work if the username matches the 1st row of your members table. It'd be best to query only rows where the username matches what they've entered. Note there's a big security risk if you just concatenate strings together for the query, so you should use prepared statements (https://websitebeaver.com/prepared-statements-in-php-mysqli-to-prevent-sql-injection)

Force user to logout session PHP

I can't seem to find a straightforward answer to this question. Is there a way in which I can force a logged in user to logout? My login system essentially just relies on a session containing the user's unique ID (which is stored in a mysql database). So essentially just...
if (isset($_SESSION['user_id'])) {
echo "You're logged in!";
} else {
echo "You need to login!";
}
But let's say I want to ban this user, well I can change their status to banned in my database but this won't do anything until the user logs out and attempts to log back in... So, how do I force this user to logout? Preferably without checking every single time they view a page whether or not their status has been switched to "banned" because that seems like unnecessary stress on my server. Any help is appreciated, thank you.
Either you need to check every time they load a page, or possibly look at an Ajax call at set intervals to check their status from the DB.
Then you can use session_destroy(); to end their session. This will destroy their entire session.
Otherwise you can use unset($_SESSION['user_id']); to unset a single session variable
Preferably without checking every single time they view a page whether or not their status has been switched to "banned" because that seems like unnecessary stress on my server.
Loading the user from the database on every page load, rather than storing a copy of the user in the session, is a perfectly reasonable solution. It also prevents the user from getting out of sync with the copy in the database (so that, for instance, you can change a user's properties or permissions without them having to log out and back in).
Try to put this on every page...
if (isset($_SESSION['user_id'])) {
$sql = "SELECT from tbl where status='banned' and user_id=$_SESSION['user_id'] ";
$query = mysql_query($sql);
if(!empty(mysql_num_rows($query))){ // found the banned user
//redirect to logout or
//session_destroy();
}
} else {
echo "You need to login!";
}
if the user is still logged in... check if his/her status is banned or not... if banned.. then logout
You can unset it.
unset($_SESSION['user_id'])
You could use Custom Session Handlers this way you have full control where and how the session data is stored on the server.
So you could store the session data for a particular user in a file called <user_id>.session for example. Then, to logout the user, just delete that file.
Ajax calls in an interval will put extra load on server. If you want real-time response to your actions(e.g. the user will be signed out right when you ban them from your system backend), then you should look into something like Server Push.
The idea is to keep a tunnel open from Server to Browser whenever a user is browsing your website, so that you can communicate with them from server-side too. If you want them to be banned, push a logout request and the process that in your page(i.e. force logout by unsetting session).
This worked for me am using pHP 5.4
include 'connect.php';
session_start();
if(session_destroy())
{
header("Location: login.php");
}
You can use session_save_path() to find the path where PHP saves the session files, and then delete them using unlink().
Once you delete the session file stored in the sever, the client side PHPSESSID cookie will no longer be valid for authentication and the user will be automatically be logger out of your application.
Please be very careful while using this approach, if the path in question turns out to be the global /tmp directory! There's bound to be other processes other than PHP storing temporary data there. If PHP has its own directory set aside for session data it should be fairly safe though.
There is a few ways to do this the best in my opinion based on security is:
NOTE: THIS IS REALLY ROUGH.... I know the syntax is wrong, its just for you to get an idea.
$con = mysql_connect("localhost","sampleuser","samplepass");
if (!$con)
{
$error = "Could not connect to server";
}
mysql_select_db("sampledb", $con);
$result = mysql_query("SELECT * FROM `sampletable` WHERE `username`='".$_SESSION['user_id']."'");
$userdeets = mysql_fetch_array($result);
if($_SESSION['sessionvalue'] != $userdeets['sessionvalue'])
{
session_destroy();
Header('Location: logout.php');
}
else
{
$result2 = mysql_query("UPDATE `sessionvalue` WHERE `username`='".$_SESSION['user_id']."' SET `sessionvalue` = RANDOMVALUE''");
$sesval = mysql_fetch_array($result2);
$_SESSION['sessionvalue'] = $seshval
}
Now I know thats not the very code but in essence what you need to do to be secure and have this ability is:
Everytime a page load check a Session value matches a value in the DB.
Every time a page loads set a new session value based on a random generated DB value. you will need to store the username in a session as well.
if the Session ID's do not match then you destroy the session and redirect them.
if it does match you make the new session ID.
if you want to ban a user you can set their sessionvalue in the DB to a value like "BANNED". this value will not allow them to log in either. this way you can control user through a simple web form and you can also generate list of banned users very easily etc etc. I wish I had more time to explain it I hope this helps.

Limit user to their profile page

On my website I have a user login system, when they login they are taken to their profile page, which is deism ate by their uid. The thing is, there was nothing to stop a user just changing the uid and going to someone else's profile and Acting as them. To stop this I implemented a URL/MySQL system by which if the uid of the user is not the uid in the URL, they are redirected to their own profile. The problem here is that on the profile there are forms which change the URL, in doing so removing the uid query, resulting in the page (because the uid is missing) taking you to your profile and ignoring the form input.
The code is:
<?php
mysql_connect ('x', 'x', 'x');
mysql_select_db ('x');
if(isset($_COOKIE['wd_un'])) {
$un = $_COOKIE['wd_un'];
$pass = $_COOKIE['wd_pass'];
$cook = "SELECT * FROM x WHERE username = '$un' AND password = '$pass' limit 1";
$cookr = mysql_query($cook) or die (mysql_error());
if(mysql_num_rows($cookr) == 0) {
header ("Location: index.php");
}
else {
$urluid = mysql_real_escape_string($_GET['uid']);
$uidcheck = "SELECT * FROM x WHERE username = '$un' AND password = '$pass'";
$uidcheckq = mysql_query($uidcheck) or die (mysql_error());
while($rcu = mysql_fetch_assoc($uidcheckq)) {
$dbuid = $rcu['uid'];
if($urluid != $dbuid) {
header ("location: home.php?uid=$dbuid");
}
else {
}
}
}
}
mysql_close();
?>
Is there a work around?
This code block you have here is riddled with badness.
First, you should absolutely never store a user's password in a cookie.
You SHOULD store only a session ID in the cookie, then store the rest of the session data in a session table in your DB that contains the user's id and any other things that you may want to have basic access to... password should not be in this table either.
Now, you can use the user_id in the URL safely cause the cross reference will keep people out.
on load of course you cross reference the mysql result from your session table that was pulled based on your cookie id. Obviously boot them if they don't match.
As for your form redirecting, you need to restructure how you handle posting then. You can make your profile page always pull only the profile related to the session id in your cookie. That would remove the dependency on URL and solve this problem completely.
Also - Please look into mysql_real_escape_string() to sanitize your inputs. It is incredibly dangerous to blindly accept cookie info for a mysql query. Unless you really do aim to leave huge injection holes in your site.
You should be using the Cookie ID to identify the user rather than pulling the user if from the URL. If cookieID does not match UserID, then redirect to their own profile.
Basically, never use the url to pass user ids for private data. Always references the cookie.
Relying on only the URL string to identify a user is a HUGE security hole on top of the usability issue you've described.

Why does my session-based login system not work?

I have just started learning PHP, and I wrote an account system with PHP and mySQL for my website. I know the sql stuff is working fine, the problem is my PHP session.
When I go to test it, I can try to login, and it fails. Then, I try to login again, and it will succeed. It always succeeds on the second attempt to login. It never succeeds on the first attempt in Firefox, but it does in Chrome. Also, a couple of times in Chrome, after I succeeded in logging in, going to a some different pages on my site seemed to erase the session. Or, at least, that session was not registering on those other pages. I didn't have that problem on Firefox. I have checked, double-checked, and triple-checked, and all of my pages call session_start() before anything else, so I know that can't be the problem.
I must not have a full enough understanding of PHP sessions, as it's just not working consistently.
After posting this, I tested in IE, and everything works fine there. I log in on the first attempt, and any page I visit maintains my session.
Here is the code for the php script that actually "logs in" the user:
<?php
session_start();
//pass info to mysql(servername, username, password)
$connect = mysql_connect ("localhost", "ggstudio", "mtgertai1");
if (!$connect)
{
die ('Failed to connect: ' . mysql_error());
}
mysql_select_db("ggstudio_accountDatabase", $connect);
//capture data sent to page through login
//usernameField and passwordField
$usernameSubmission = $_POST[usernameField];
$passwordSubmission = $_POST[passwordField];
$validAccount = mysql_query("SELECT * FROM userAccounts WHERE userID = '$usernameSubmission' AND userPassword = '$passwordSubmission'");
$row = mysql_fetch_array($validAccount);
if (($row['userID'] == $usernameSubmission)&&($row['userPassword'] == $passwordSubmission))
{
/*********************************
**********************************
assign global variables to session
after starting session and then***
redirect to user homepage*********
**********************************
**********************************
*/
//get account number from database
$_SESSION['accountNumber']= $row['accountNumber'];
//get first name from database
$_SESSION['firstName']= $row['firstName'];
//get last name from database
$_SESSION['lastName']= $row['lastName'];
//save username into session
$_SESSION['username']= $row['userID'];
//save password into session (only really useful if user wants to change password)
$_SESSION['userPassword']= $row['userPassword'];
//get user's email address from database
$_SESSION['userEmail']= $row['userEmail'];
//get GP from database
$_SESSION['gpoints']= $row['userGloryPoints'];
//get user join date from database
$_SESSION['userJoinDate']= $row['userJoinDate'];
//get user rank
$_SESSION['userRank']= $row['userRank'];
header('Location: http://www.glorygamer.com/account_home.php');
}
else
{
$loginFailed= TRUE;
setcookie("incorrectLogin", $loginFailed, time()+20);
header('Location: http://www.glorygamer.com/shibboleth.php');
}
?>
If the session is working intermittently then I'd say there's one of two things happening:
Your session isn't being set in the browser correctly
Your session isn't being saved on the server in time.
One thing that can happen (especially when you're testing on localhost) is that an authenticated session isn't written to disk in time for the next request, hence the next request appears to be un-authenticated (remember that apache is multi-process; your second request could be handled by another process which isn't aware of what the first is doing). Here's one possible solution:
$_SESSION['userRank']= $row['userRank'];
session_write_close();
header('Location: http://www.glorygamer.com/account_home.php');
The call to session_write_close() should mean that your authenticated session is ready in time for the next request.
HTH.
The first thing I see are the lack of single quotes. Also, you should definitely escape these so that nobody can do any SQL injection on you.
$usernameSubmission = $_POST[usernameField];
$passwordSubmission = $_POST[passwordField];
should be:
$usernameSubmission = mysql_real_escape_string($_POST['usernameField']);
$passwordSubmission = mysql_real_escape_string($_POST['passwordField']);

Why do my sessions persist on other pages when visited manually but not when following a link?

I created a user account system for my website using PHP sessions and mySQL. I have been trying for SO LONG to get it to work right. The very first night it worked 'mostly' right. And I have made almost no progress since then. I've been researching and googling until I've burnt out, and I haven't figured it out.
The problem is, I can create user accounts fine, and it registers as planned in my sql database, and I can even login correctly. However, when I go to other pages on my site, the session doesn't seem to be registered on those pages. I check for the user's session with
if (isset($_SESSION['username']))
and if they are not logged in, a 'login' button appears in main menu on every page. If they are logged in, a button with their username appears that links to their account page. If you would like to see for yourself, www.glorygamer.com is the website and you can use testAccount with password as the password to login and see.
Here's the weird part. Today I made a discovery, and now I am CERTAIN it isn't a problem with my PHP script. If I manually enter in the page I want to visit (if I literally type "www.glorygamer.com/account_home.php" then it works perfectly. The session always starts properly with any page I visit in this way. However, when I click on links in my menu, it seems to work almost at random. Sometimes I will be sent to the next page and the session will be started correctly, and sometimes it won't be.
Is there some special way I need to link my pages, even though they all correctly session_start() before anything else?
Here is the login script:
<?php session_start();
//pass info to mysql(servername, username, password)
$connect = mysql_connect ("localhost", "***", "***");
if (!$connect)
{
die ('Failed to connect: ' . mysql_error());
}
mysql_select_db("ggstudio_accountDatabase", $connect);
//capture data sent to page through login
//usernameField and passwordField
$usernameSubmission = $_POST['usernameField'];
$passwordSubmission = $_POST['passwordField'];
$validAccount = mysql_query("SELECT * FROM userAccounts WHERE userID = '$usernameSubmission' AND userPassword = '$passwordSubmission'");
$row = mysql_fetch_array($validAccount);
if (($row['userID'] == $usernameSubmission)&&($row['userPassword'] == $passwordSubmission))
{
/*********************************
**********************************
assign global variables to session
after starting session and then***
redirect to user homepage*********
**********************************
**********************************
*/
//get account number from database
$_SESSION['accountNumber']= $row['accountNumber'];
//get first name from database
$_SESSION['firstName']= $row['firstName'];
//get last name from database
$_SESSION['lastName']= $row['lastName'];
//save username into session
$_SESSION['username']= $row['userID'];
//save password into session (only really useful if user wants to change password)
$_SESSION['userPassword']= $row['userPassword'];
//get user's email address from database
$_SESSION['userEmail']= $row['userEmail'];
//get GP from database
$_SESSION['gpoints']= $row['userGloryPoints'];
//get user join date from database
$_SESSION['userJoinDate']= $row['userJoinDate'];
//get user rank
$_SESSION['userRank']= $row['userRank'];
session_write_close();
header('Location: http://www.glorygamer.com/account_home.php');
exit;
}
else
{
$loginFailed= TRUE;
setcookie("incorrectLogin", $loginFailed, time()+20);
session_write_close();
header('Location: http://www.glorygamer.com/shibboleth.php');
exit;
}
?>
It sucks, I am lacking 6 points for commenting on questions, thus I have to use an answer… In my tests it rather seemed your problem is script dependant as I cannot see the logged in status on the top right even if I am visiting another URL (e.g. www.glorygamer.com/index.php) from outside. That’s obviously clear, as there is nothing different between a link and the same URL without a link except the Referer header.
The only site which I can see my logged in status on is the mentioned www.glorygamer.com/account_home.php
The session cookie is always existing and sent (checked with Live HTTP Headers) and therefore must also be reiceved on index.php (where the username is not displayed in the top right corner, but instead "Login").
So you should check if session_start() really works in these files. Also check for posibble surpressed error messages, as session_start() would throw an error if there was any output before session_start() (either via echo, var_dump, print, print_r or pure HTML outside of PHP blocks). I am not sure if you can oppress that error messages, but I guess you can with the "right" server settings.
Hope my hints can get you a little further to your solution.
This comment on php.net sounds like a similar situation to the one you're in, though I don't know why session_write_close would cause the problem you're having.
Rather than replace with session_regenerate_id() as the comment suggests, I'd recommend you simply remove session_write_close() to see if this bears fruit.
It's not an answer to the actual question, but nevertheless important:
Please always escape any user-input data before passing it along to the database.
This:
$usernameSubmission = $_POST['usernameField'];
$passwordSubmission = $_POST['passwordField'];
$validAccount = mysql_query("SELECT * FROM userAccounts WHERE userID = '$usernameSubmission' AND userPassword = '$passwordSubmission'");
should read:
// Any data entered by a third party is insecure
$usernameInsec = $_POST['usernameField'];
$passwordInsec = $_POST['passwordField'];
// Protect your SQL statements
$validAccount = mysql_query(
"SELECT * FROM userAccounts "
. " WHERE userID = '" . mysql_escape_string( $usernameInsec ) . "' "
. " AND userPassword = '" . mysql_escape_string( $passwordInsec )
. "'"
);

Categories