PHP PDO Logging Into Account - php

<?php
function login($database, $username, $password) {
$query = "SELECT * FROM `users` WHERE username=':username'";
$query = $database->prepare($query);
$query->execute(array(':username' => $username));
$rowcount = $query->rowCount();
if($rowcount == 1){
$row = mysql_fetch_array($query);
$dbPass = $row["password"];
if($password == $dbPass){
session_start();
$dbId = $row["id"];
$dbUser = $row["username"];
$dbEmail = $row["email"];
$dbFirstname = $row["firstname"];
$dbLastname = $row["lastname"];
//Register Session Variables
$_SESSION['id'] = $dbId;
$_SESSION['username'] = $dbUser;
$_SESSION['email'] = $dbEmail;
$_SESSION['name'] = $dbFirstname." ".$dbLastname;
return true;
} else
return false;
} else
return false;
}
?>
This is a PHP code snippet from a project I am globally converting to PDO. This is the functions.php file for the login page. Obviously it is not fully converted to PDO so don't criticize that, but basically in the login.php file I have it access this method, and pass the database(which is required in), the username, and the password from the form. I setup a basic query to find all users with the username input of the form. Then i prepare, and execute the query. I then need a row count, so I setup a $rowcount variable running the rowCount() method on the query, but the code does not move past there. The rowcount is == 0 when I echo it out so it won't proceed to the following if statement. Am I doing something wrong with the PDO or something? Or the rowCount(). My suspicion is that perhaps I am calling the rowCount() too late, so I tried moving it up before I execute the $query but no luck. Thank you!
___EDIT___
<?php
session_start();
function login($database, $username, $password) {
$query = "SELECT * FROM `users` WHERE username=':username'";
$query = $database->prepare($query);
$query->execute(array(':username' => $username));
if($query->rowCount()){
$row = $query->fetch();
echo $row;
$dbPass = $row["password"];
if($password == $dbPass){
$dbId = $row["id"];
$dbUser = $row["username"];
$dbEmail = $row["email"];
$dbFirstname = $row["firstname"];
$dbLastname = $row["lastname"];
//Register Session Variables
$_SESSION['id'] = $dbId;
$_SESSION['username'] = $dbUser;
$_SESSION['email'] = $dbEmail;
$_SESSION['name'] = $dbFirstname." ".$dbLastname;
return true;
} else {
return false;
}
} else {
return false;
}
}
?>

Don't mix pdo and mysql_ functions together. NEVER!
Don't store password in plain text. NEVER! Instead try Password_compat !
First:
Is to replace
$row = mysql_fetch_array($query);
with
$query->fetchAll(PDO::FETCH_ASSOC)
Second:
session_start() should appear at the top of your script, not inside your function.
Third:
Is to replace
$rowcount = $query->rowCount();
if($rowcount == 1){
//
}
with this:
if($query->rowCount()){}
Fourth:
This is BAD!!
return true;
} else
return false;
} else
return false;
}
Always, use a complete delimiter. You are instilling a bad-codding practice, that will haunt you for life.
Simple do
if($foo){
if(){
//do something
}else if{
//do something
}else{
//do something
}
}
Fifth:
~Not good, but definitely better that your approach.
function small_query(pdo $pdo, $query, array $value){
$stmt = $pdo->prepare($query);
$stmt->execute($value);
return $stmt->fetchAll();
}
$pdo = new PDO('mysql:host=localhost; dbname=foo', 'root', 'pass');
$result = small_query($pdo, "SELECT * FROM users WHERE name = ?", array($_POST['name']))
EDIT.
Since you seem to love your code so much, I have done it your way. Try this:
<?php
session_start();
function login($database, $username, $password){
$query = "SELECT * FROM users WHERE username = ?";
$stmt = $database->prepare($query);
$stmt->execute(array($username));
if($stmt->rowCount()){
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$_SESSION["id"] = $result["id"];
$_SESSION["username"] = $result["username"];
$_SESSION["email"] = $result["email"];
return true;
}else{
return false;
}
}

Related

How can I get a string from a function

So, this is my code:
class Functions{
public static function login($email,$password){
$email = $_GET['email'];
$password = $_GET['password'];
if(isset($_GET['submit']) AND isset($email) AND isset($password)){
$password = md5($password);
$sql = "SELECT * FROM users WHERE email='$email' AND password='$password'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$_SESSION['nume'] = $row["name"];
$_SESSION['uid'] = $row["id"];
$_SESSION['admin'] = $row["admin"];
$_SESSION['email'] = $row["email"];
$_SESSION['points'] = $row["points"];
}else{
$errortxt = "Invalid Login Credentials";
$error = true;
}
}
return $error;
}
}
In my HTML file I'm calling for the function like this:
Function::login($email,$password);
But I'm wondering how can I get the $errortxt string to echo in the HTML file.
Thanks!
You just need a simple fix:
class Functions{
public static function login($email,$password){
$response['error'] = false;
$response['errortxt'] = "";
$email = $_GET['email'];
$password = $_GET['password'];
if(isset($_GET['submit']) AND isset($email) AND isset($password)){
$password = md5($password);
$sql = "SELECT * FROM users WHERE email='$email' AND password='$password'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
$_SESSION['nume'] = $row["name"];
$_SESSION['uid'] = $row["id"];
$_SESSION['admin'] = $row["admin"];
$_SESSION['email'] = $row["email"];
$_SESSION['points'] = $row["points"];
}else{
$response['error'] = true;
$response['errortxt'] = "Invalid Login Credentials";
}
}
return $response;
}
}
And you need to call it this way:
$fnCallStatus = Function::login($email,$password); //Now you have the response;
if($fnCallStatus['error']) //we have an error
{
echo $fnCallStatus['errortxt']; //we print the message
}
Hi I fixed little bit your code because it lacks good coding principles and good taste (calling superglobal $_GET variable will always get you something after request despite you place something else into function parameters).
class Functions{
public static function login($email,$password)
{
$error['is'] = true;
$email = htmlspecialchars($email);
$password = md5(htmlspecialchars($password));
if(!empty($email) AND !empty($password))
{
$sql = "SELECT * FROM users WHERE email='$email' AND password='$password'";
$result = $conn->query($sql);
if ($result->num_rows > 0)
{
$row = $result->fetch_assoc();
$_SESSION['nume'] = $row["name"];
$_SESSION['uid'] = $row["id"];
$_SESSION['admin'] = $row["admin"];
$_SESSION['email'] = $row["email"];
$_SESSION['points'] = $row["points"];
} else {
$error['mismatch'] = "Email or password does not match.";
return $error;
}
} else {
$error['empty'] = "Please fill all login fields. Thank you";
return $error;
}
}
}
$error = Function::login($_GET['email'],$_GET['password']);
if($error['is'])
{
if ($error['mismatch']) {
echo $error['mismatch'];
} elseif ($error['empty']) {
echo $error['empty']
}
}
Your function also always return $error despite none occurred. I fixed that and function return error only in not query case.
Functions can return arrays. So if you need to set multiple fields with different text, you can place into array anything you like. This solution is more buletproof.

Switched from mysql_ to PDO, login script no longer working

I replaced my mediocre mysql_* query system with PDO. However, my login script stopped working. It has to be a problem with fetching data, since my username passes, but my password does not.
CODE:
<?php
session_start();
include('config.php');
include('cipher.php');
$usercheck = $_POST["email"];
$passcheck = $_POST["pass"];
$stmt = $pdo->prepare('SELECT * FROM users WHERE email = :usercheck');
$stmt->execute(array(
':usercheck' => $usercheck
));
$num = $stmt->rowCount();
if ($num == 1) {
$bcrypt = new Bcrypt(15);
$record = $stmt->fetchAll();
$hash = $record['password'];
$isGood = $bcrypt->verify($passcheck, $hash);
if ($isGood == 1) {
$_SESSION['fname'] = $record['firstname'];
$_SESSION['lname'] = $record['lastname'];
$_SESSION['email'] = $record['email'];
$_SESSION['user'] = $record['email'];
$_SESSION['uid'] = $record['uid'];
$_SESSION['birthday'] = $record['birthday'];
$_SESSION['type'] = $record['pagetype'];
$_SESSION['backcolor'] = $record['backcolor'];
$_SESSION['barcolor'] = $record['barcolor'];
$_SESSION['activated'] = $record['activated'];
if ($_SESSION['activated'] == 0) {
$_SESSION['newemail'] = $record['email'];
unset($_SESSION['fname']);
unset($_SESSION['lname']);
unset($_SESSION['email']);
unset($_SESSION['user']);
unset($_SESSION['uid']);
unset($_SESSION['birthday']);
unset($_SESSION['type']);
unset($_SESSION['backcolor']);
unset($_SESSION['barcolor']);
header('Location: mustactivate.php');
} else {
if ($_SESSION['type'] == 1) {
header('Location: profile.php');
} else {
if ($_SESSION['type'] == 2) {
header('Location: mypage.php');
} else {
header('Location: setup.php');
}
}
}
} else
header('Location: login.php?error=badpass');
} else
header('Location: login.php?error=bademail');
?>
$record = $stmt->fetchAll();
$hash = $record['password'];
The fetchAll() method returns an array of rows. So there will not be any $record['password'].
Try var_dump($record) to show yourself what's in that variable.
To fix this, you could use $record[0]['password']. Or else you could fetch it with $stmt->fetch() if you just need one row.
Simply because fetchAll will return an array, so use $record[0] instead of $record directly ex: $record[0]['password']
or after $record = $stmt->fetchAll(); add $record = $record[0]; and leave all the rest to $record['field_name']

Insert data (only 1 time) in while loop using PHP

I have the PHP code as below:
<?php
if(isset($_POST["tbn_submit"])){
$userName = $_POST["text_username"];
$pass = $_POST["text_password"];
//$sql = "SELECT * FROM tbluser WHERE username='".$userName."' AND password='".$pass."'";
$sql = "SELECT * FROM tbluser";
$res = mysql_query($sql) or die(mysql_error());
if(mysql_num_rows($res)>0){
while($row= mysql_fetch_array($res)){
$username=$row['username'];
$userpas = $row['password'];
$user_id=$row['userId'];
$user_role=$row['possition'];
$_SESSION['username'] = $username;
$_SESSION['uid'] = $user_id;
if($userName == $username && $pass == $userpas){
if($user_role=="Admin"){
echo'<script>window.location="admin_project.php?uid='.$user_id.'";</script>';
}else{
echo'<script>window.location="user_project.php?uid='.$user_id.'";</script>';
}
}
else if($userName == $username && $pass != $userpas){
echo "<span style='text-align:center;color:red;'>Wrong password.</span>";
}
else if($userName != $username && $pass != $userpas){
//In this point I got insert multi time so I want it insert only 1 time to database
$query = "INSERT INTO tbluser(userId,username,password,possition,user_status) VALUES('','".$userName."','".$pass."','',1)";
$result = mysql_query($query) or die(mysql_error());
$id = mysql_insert_id();
if($result){
echo'<script>window.location="user_project.php?uid='.$user_id.'";</script>';
}
}
}
}else {
echo "re";
}
}
?>
This is my login page submission. When the user inputs their username and password, if the username and password are already in the database it will go to test some case like in code, but if the username is in the database but the password does not match it should display wrong password..
If the username and password don't exist in the database, the program should create username and password and go to other page. I have an error with this last case - I have inserted a lot of records in the database with the same data. I know it's because I wrote these entries in a while loop in my code but I don't know any other way of doing this. How can I populate my database with individual records and not write duplicate entries in my while loop?
All your logic is wrong:
there's no need to retrieve ALL the users to check if the user exists,
tbluser should restrict username to be UNIQUE to avoid duplicated entries,
passwords should be hashed,
the INSERT query uses unescaped variables,
inserting non matching user names will lead to have typos stored at the db,
mysql_* family of functions are deprecated
Using PDO
Login user
<?php
$dbh = new PDO('mysql:host=localhost;dbname=some_database_name', $user, $pass);
if (isset($_POST["login"])) {
$user = $_POST["username"];
$pass = $_POST["password"];
$statement = $dbh->prepare("SELECT * FROM tbluser WHERE username=:user");
$statement->bindParam(':user',$user);
$statement->execute();
/**
* Returns FALSE in case nothing is found
*/
$res = $statement->fetch(PDO::FETCH_ASSOC);
if ($res) {
$username = $res['username'];
$password = $res['password'];
$user_id = $res['userId'];
$user_role = $res['possition'];
if ($pass == $password) {
$_SESSION['username'] = $username;
$_SESSION['uid'] = $user_id;
if ($user_role == "Admin") {
echo'<script>window.location="admin_project.php?uid='.$user_id.'";</script>';
}
else {
echo'<script>window.location="user_project.php?uid='.$user_id.'";</script>';
}
}
else {
echo "<span style='text-align:center;color:red;'>Wrong password.</span>";
}
}
else {
echo "<span style='text-align:center;color:red;'>Wrong username.</span>";
}
}
Register user
<?php
$dbh = new PDO('mysql:host=localhost;dbname=some_database_name', $user, $pass);
if (isset($_POST["register"])) {
$user = $_POST["username"];
$pass = $_POST["password"];
$check = $_POST["passcheck"];
$statement = $dbh->prepare("SELECT * FROM tbluser WHERE username=:user");
$statement->bindParam(':user',$user);
$statement->execute();
/**
* Returns FALSE in case nothing is found
*/
$res = $statement->fetch(PDO::FETCH_ASSOC);
if ($res) {
echo "<span style='text-align:center;color:red;'>Username exists.</span>";
}
else if ($pass != $check) {
echo "<span style='text-align:center;color:red;'>Password check doesn't match.</span>";
}
else {
$statement = $dbh->prepare("INSERT INTO tbluser (userId, username, password, position, user_status) VALUES ('', :user, :pass, '' , 1)");
$statement->bindParam(':user',$user);
$statement->bindParam(':pass',$pass);
$statement->execute();
echo "<span style='text-align:center;color:red;'>Username registered.</span>";
}
}
Using mysql_query (deprecated)
To validate any user:
<?php
if (isset($_POST["login"])) {
$user = $_POST["username"];
$pass = $_POST["password"];
/**
* This line had the right idea!
*/
$sql = "SELECT * FROM tbluser WHERE username='".mysql_real_escape_string($user)."'";
$res = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($res) > 0) {
$username = $row['username'];
$password = $row['password'];
$user_id = $row['userId'];
$user_role = $row['possition'];
if ($pass == $password) {
$_SESSION['username'] = $username;
$_SESSION['uid'] = $user_id;
if ($user_role == "Admin") {
echo'<script>window.location="admin_project.php?uid='.$user_id.'";</script>';
}
else {
echo'<script>window.location="user_project.php?uid='.$user_id.'";</script>';
}
}
else {
echo "<span style='text-align:center;color:red;'>Wrong password.</span>";
}
}
else {
echo "<span style='text-align:center;color:red;'>Wrong username.</span>";
}
}
To register some user:
<?php
if (isset($_POST["register"])) {
$user = $_POST["username"];
$pass = $_POST["password"];
/**
* Ask the user to type its password twice
*/
$check = $_POST["passcheck"];
$sql = "SELECT * FROM tbluser WHERE username='".mysql_real_escape_string($user)."'";
$res = mysql_query($sql) or die('The application found a problem and cannot process your request'); // die(mysql_error());
if (mysql_num_rows($res) > 0) {
echo "<span style='text-align:center;color:red;'>Username exists.</span>";
}
else if ($pass != $check) {
echo "<span style='text-align:center;color:red;'>Password check doesn't match.</span>";
}
else {
$query = "INSERT INTO tbluser (userId, username, password, possition, user_status) VALUES ('','".mysql_real_escape_string($user)."','".mysql_real_escape_string($pass)."','',1)";
$res = mysql_query($sql) or die('The application found a problem and cannot process your request'); // die(mysql_error());
echo "<span style='text-align:center;color:red;'>Username registered.</span>";
}
}

Convert MySQL login script to PDO

I've written a functional login script using MySQL. However, I've now been told that it needs to be done using PDO, and I've a functional PDO connection:
function getConnection()
{
$userName = '*****';
$password = '*****';
$dbname = '******';
$db = new PDO("mysql:host=localhost;dbname=$dbname", $userName, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
However I've no idea how to convert the login query to PDO.
if (isset($_REQUEST['attempt']))
{
$user = $_POST['user'];
$password = $_POST['password'];
$qry = mysql_query
("SELECT *
FROM subscriber
WHERE email = '$user'
AND password = '$password'")
or die(mysql_error());
$total = mysql_num_rows($qry);
if ($total > 0)
{
session_start();
$_SESSION['user'] = 'yes';
header('location: account.php');
exit;
}
else
{
// Do nothing.
}
}
How can I do it?
To get you started:
$db = getConnection();
$stmt = $db->prepare("
SELECT * FROM subscriber WHERE email = :email AND password = :password
");
$stmt->bindParam(":email" , $user );
$stmt->bindParam(":password", $password);
$stmt->execute();
$total = $stmt->rowCount();
Non-bloated version:
$stm = $pdo->prepare("SELECT * FROM subscriber WHERE email = ? AND password = ?");
$stm-> execute($_POST['user'], $_POST['password']);
if ($id = $stm->fetchColumn()) {
session_start();
$_SESSION['user'] = $id;
header('location: account.php');
exit;
}
You can also use this example if you would not like to use bindParam. But I extracted it from #eggyal's answer. Great thanks go to eggyal.
<?php session_start();
include_once('pdo.inc.php');
$username = (isset($_POST['username']))? trim($_POST['username']): '';
$password = (isset($_POST['password']))? $_POST['password'] : '';
$pas = md5($password);
$redirect = (isset($_REQUEST['redirect']))? $_REQUEST['redirect'] :
'view.php';
$query = ("SELECT username FROM site_user WHERE username=:username
AND password =:password");
$query_login = $con->prepare($query);
$query_login->execute(array(
':username'=>$username,
':password'=>$pas));
$result = $query_login->rowCount();
if($result>0)
{
$_SESSION['username'] = $username;
$_SESSION['logged'] = 1;
echo "success";
}
else {
// Set these explicitly just to make sure
echo 'User name invalid';
}
?>

Setting session variable from query result

I've been modifying a user authentication system and I'm having trouble setting a session for the admin. The reguser session is setting just fine, but I can't figure out why admin won't set.
A user with a userlevel of 9 is an admin. Yes, I know how to protect against SQL injection. I'm just trying to keep it as simple and easy to read for now. This probably won't get used for anything, I'm just getting some experience with PHP.
Hi everyone, thanks for your help! I got it to work. I had been staring at it for so long that my mind wasn't clear. Took a break from it yesterday, came back to it today and was able to figure it out in less than 5 minutes! You guys are awesome, I love stackoverflow!
function checklogin($email, $pass) {
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(udogoo, $connection) or die(mysql_error());
$pass = md5($pass);
$result = mysql_query("SELECT userid from users WHERE email = '$email' AND password = '$pass'");
$user_data = mysql_fetch_array($result);
$no_rows = mysql_num_rows($result);
if ($no_rows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
$userid = $user_data['userid'];
$isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = '$userid'");
$isadmin2 = mysql_fetch_array($isadmin);
$isadmin3 = $isadmin2['userlevel'];
if ($isadmin3 == "9"){
$_SESSION['admin'] = true;
return true;
}
}
else
{
return FALSE;
}
}
You have a return true; if the user data exists. In fact, you only check or admin-ness if the user doesn't exist.
Remove that return true;, as it's not needed there. If you want, add else return false; after the check for the user's existence, and return true; right at the end.
Your logic is flawed as well, here:
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(test, $connection) or die(mysql_error());
$email = mysql_real_escape_string($email);
$pass = md5($pass);
$sql = "SELECT `userid`,`userlevel`
FROM `users`
WHERE `email` = '$email'
AND `password` = '$pass'
LIMIT 1"; //I certainly hope you check email for injection before passing it here. Also want the LIMIT 1 on there because you are only expecting a single return, and you should only get one since `email` should be unique since you're using it as a credential, and this will stop it from looking through all the rows for another match once it finds the one that matches.
$result = mysql_query($sql);
$user_data = mysql_fetch_array($result);
$numrows = mysql_num_rows($result);
if ($numrows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
if($user_data['userlevel'] == 9)
{
$_SESSION['admin'] = true;
}
else
{
$_SESSION['admin'] = false;
}
return true;
}
return false;
}
This should work. No good reason to do two queries when one will do just fine. Returns true if user is logged in, false if user doesn't exist or credentials don't match.
Oops, small syntax error in the SQL statement, corrected. Bigger syntax error also corrected.
And here's how you do the top part in PDO:
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$dbname = 'test';
$dsn = 'mysql:dbname=' . $dbname . ';host=' . $server;
$conn = new PDO($dsn,$user,$password); //Establish connection
$pass = md5($pass);
$sql = "SELECT `userid`,`userlevel`
FROM `users`
WHERE `email` = :email
AND `password` = :pass
LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bindParam(':email',$email,PDO::PARAM_STR,128) //First param gives the placeholder from the query, second is the variable to bind into that place holder, third gives data type, fourth is max length
$stmt->bindParam(':pass',$pass,PDO::PARAM_STR,32) //MD5s should always have a length of 32
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$stmt->execute(); //almost equivalent to mysql_query
$user_data = $stmt->fetch(); //Grab the data
if(is_array($user_data) && count($user_data) == 2) //Check that returned info is an array and that we have both `userid` and `userlevel`
{
//Continue onwards
$userid = $user_data['user_id'];
$isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = $userid");
$user_data = mysql_fetch_array($result);
$userlevel = $user_data['userlevel'];
if($userlevel == '9')
{
$_SESSION['admin'] = true;
}
so, your complete code look like this::
<?php
function checklogin($email, $pass)
{
$server = 'localhost';
$user = 'root';
$password = '';
$connection = mysql_connect($server, $user, $password) or die(mysql_error());
mysql_select_db(test, $connection) or die(mysql_error());
$pass = md5($pass);
$result = mysql_query("SELECT userid from users WHERE email = '$email' AND password = '$pass'");
$user_data = mysql_fetch_array($result);
$numrows = mysql_num_rows($result);
if ($numrows == 1)
{
$_SESSION['reguser'] = true;
$_SESSION['userid'] = $user_data['userid'];
//MY ANSWER START HERE
$userid = $_SESSION['userid'];
$isadmin = mysql_query("SELECT userlevel FROM users WHERE userid = $userid");
$user_data = mysql_fetch_array($result);
$userlevel = $user_data['userlevel'];
if($userlevel == '9')
{
$_SESSION['admin'] = true;
}
//END HERE
}
else
{
return false;
}
}
?>

Categories