so I have this site where drivers can login and register.
at the moment i can store the username in a session variable, im trying to do the same for the user_id so the user can later retrieve it when adding more details for a job.
heres what I got so far:
function selectUser($conn, $username, $password, $userID)
{
$query = "SELECT * FROM login WHERE username = :username";
$stmt = $conn->prepare($query);
$stmt->bindValue(':username', $username);
//$stmt->bindValue(':user_ID', $userID);
$stmt->execute();
if ($row = $stmt->fetch(PDO::FETCH_OBJ))
{
if (md5($password) == $row->password) {
$_SESSION['username'] = $username;
$_SESSION['user_ID'] = $userID;
// $_SESSION['password'] = $password;
echo "Welcome, you are now logged in as " . $username;
return true;
}
return false;
}
else
{
//echo "Your details were not found";
return false;
}
}
when the driver accesses another page:
<?php
if(!isset($_SESSION))
{
session_start();
}
require_once ("config.inc.php");
try
{
$conn = new PDO(DB_DATA_SOURCE, DB_USERNAME, DB_PASSWORD);
}
catch(PDOException $exception)
{
echo "Oh no, there was a problem" . $exception->getMessage();
}
if(isset($_SESSION["username"]))
{
echo "Welcome, you are now logged in as <b>".$_SESSION['username']."</b> <img class='clientView' src='images/loginIcon.png' alt='client'>"; }
else {
echo "You are currently not logged in";
}
$login = $_SESSION['user_ID'];
$query = "SELECT * FROM login WHERE user_ID = :login";
$term = $conn->prepare($query);
$term->bindValue(':login', $login);
$term->execute();
$login = $term->fetch(PDO::FETCH_OBJ);
print_r($_SESSION);
?>
tested it using print r and for some reason it doesnt seem to be collecting the user_ID.
am i doing something wrong?
upon test: https://snag.gy/6bGd5m.jpg
when calling the function:
$username=trim($_POST['username']);
$password=$_POST['password'];
$username= htmlspecialchars($username);
$validForm = true;
if (empty($_POST["username"]))
{
$validForm=false;
}
if (empty($_POST["password"]))
{
$validForm=false;
}
if (!$validForm) {
$error = "please ensure all fields are filled in";
include("add.php");
return false;
}
$conn=getConn();
$successLogin=selectUser($conn,$username,$password);
if($successLogin)
{
header( 'Location: profile.php');
}else{
$error = "The details you have entered are incorrect";
include("add.php");
}
Debug.
Where do you store the value in the session state?:
$_SESSION['user_ID'] = $userID;
Ok, so where does $userID come from?:
function selectUser($conn, $username, $password, $userID)
{
//...
Ok, so where does the function parameter come from?:
selectUser($conn,$username,$password)
Nowhere. You never supplied a value to be stored in session, so no value was stored in session.
It seems unlikely that you actually want to supply the User ID to the function. Instead, you probably want to supply just the username and password as you currently do and then get the User ID from the database. Which might look more like this:
$_SESSION['user_ID'] = $row["user_ID"];
Or perhaps:
$_SESSION['user_ID'] = $row->user_id;
Or however you get values from your $row object.
But basically the important lesson here is... When a value isn't what you expect it to be, trace back where that value came from. Chances are you have a false assumption somewhere.
Related
I have been working for 2 days on a login and authentication system in PHP. For my logic it should be perfect, but I have problems as usual.
Here is the code:
<?php
ob_start();
session_start();
include "../navbar.php";
require_once '../database-connection.php';
include "../login.html";
if (isset($_SESSION['session_id'])) {
header('Location: ../index.php');
exit;
}
if (isset($_POST['login'])) {
$email = $_POST['email'] ?? '';
$password = $_POST['password'] ?? '';
$query = "
SELECT email, password
FROM users
WHERE email = :email
";
$check = $pdo->prepare($query);
$check->bindParam(':email', $email, PDO::PARAM_STR);
$check->execute();
$user = $check->fetch(PDO::FETCH_ASSOC);
if ($email == $user['email']) {
if (password_verify($password, $user['password'])) {
session_regenerate_id();
$_SESSION['session_id'] = session_id();
$sql = "
SELECT username, id FROM users
WHERE email = :email";
$check = $pdo->prepare($sql);
$check->bindParam(':email', $email);
$check->execute();
$user = $check->fetch();
$_SESSION['session_user'] = $user['username'];
$_SESSION['email'] = $email;
$_SESSION['user_id'] = $user['id'];
header('Location: ../index.php');
exit;
} else {
$msg = "Wrong Password";
}
} else {
$msg = "Wrong Email";
}
printf($msg, 'back');
}
The system works, it allows me to authenticate the users registered in the database, but I don't understand why the $msg variable that I use for errors is not printed.
Or better any echo that I put in any part of the listing is not printed.
I can't print anything anywhere. It looks like the program just hangs after the first few includes, yet it lets me authenticate.
(Yes guys I debug by printing the echo to understand up where the scripts work!)
some help if you wish please for beginner user
will you please show me where is my code problem ?
i want to get user id from $_SESSION['userid']
but it's not working
i success to get username but not the id
i include session_start(); on each page to want to use it
but it's not showing the user id
only username working
here are my code
<?php
include("conn.php");
// variable declaration
$userid = "";
$username = "";
$email = "";
$errors = array();
$_SESSION['success'] = "";
// call the login() function if register_btn is clicked
if (isset($_POST['login_btn'])) {
login();
}
if (isset($_GET['logout'])) {
session_destroy();
unset($_SESSION['user']);
unset($_SESSION['username']);
unset($_SESSION['userid']);
unset($_SESSION['user_type']);
header("location: ../login.php");
}
// return user array from their id
function getUserById($id){
global $conn;
$query = "SELECT * FROM users WHERE id=" . $id;
$result = mysqli_query($conn, $query);
$user = mysqli_fetch_assoc($result);
return $user;
}
// LOGIN USER
function login(){
global $conn, $username, $errors;
// grap form values
$username = e($_POST['username']);
$password = e($_POST['password']);
// make sure form is filled properly
if (empty($username)) {
array_push($errors, "Username is required");
}
if (empty($password)) {
array_push($errors, "Password is required");
}
// attempt login if no errors on form
if (count($errors) == 0) {
$password = md5($password);
$query = "SELECT * FROM users WHERE username='$username' AND password='$password' LIMIT 1";
$results = mysqli_query($conn, $query);
if (mysqli_num_rows($results) == 1) { // user found
// Storing username in session variable
session_start();
// check if user is admin or user
$logged_in_user = mysqli_fetch_assoc($results);
$userid=$row['id'];
$username=$row['username'];
$user_type=$row['user_type'];
$_SESSION['username'] = $username;
$_SESSION['userid'] = $userid; // <-this variable should now exist
$_SESSION['user_type'] = $user_type;
if ($logged_in_user['user_type'] == 'admin') {
$_SESSION['user'] = $logged_in_user;
$_SESSION['success'] = "You are now logged in";
header('location: admin/home.php');
}else{
if ($logged_in_user['user_type'] == 'superuser') {
$_SESSION['user'] = $logged_in_user;
$_SESSION['success'] = "You are now logged in";
header('location: superuser/home.php');
}else{
$_SESSION['user'] = $logged_in_user;
$_SESSION['success'] = "You are now logged in";
header('location: index.php');
}
} }else {
array_push($errors, "Wrong username/password combination");
}
}
}
function isLoggedIn()
{
if (isset($_SESSION['user'])) {
return true;
}else{
return false;
}
}
function isSuperuser()
{
if (isset($_SESSION['user']) && $_SESSION['user']['user_type'] == 'superuser' ) {
return true;
}else{
return false;
}
}
function isAdmin()
{
if (isset($_SESSION['user']) && $_SESSION['user']['user_type'] == 'admin' ) {
return true;
}else{
return false;
}
}
// escape string
function e($val){
global $conn;
return mysqli_real_escape_string($conn, trim($val));
}
function display_error() {
global $errors;
if (count($errors) > 0){
echo '<div class="error">';
foreach ($errors as $error){
echo $error .'<br>';
}
echo '</div>';
}
}
?>
As far as i can tell, your script would run.
Though please note that when using with sessions and $_SESSION globals, you have to initialise it first by adding session_start(); at the top of your page.
You should also dig into using PDO rather than mysqli or mysql.
I know this looks complicated, but it's the safest way to handle database queries.
Also don't use md5, use password_hash();
I also recommend adding var_dump($row); in this if statement, to see what data you are working with:
if (mysqli_num_rows($results) == 1) { // user found
I have problem with login system i can login with any username and password i dont how to fix
if anyone can help i would be very grateful
here my login system
function userLog() {
global $connect;
if(isset($_POST['userLog'])) {
$username = trim(protect($_POST['username']));
$password = trim(protect($_POST['password']));
if(empty($username)) {
$_SESSION['message'] = '';
header('Location: index.php');
exit();
} elseif (empty($password)) {
$_SESSION['message'] = '';
header('Location: index.php');
exit();
}
$userSQL = "SELECT * FROM users WHERE username = :username";
$userLog = $connect->prepare($userSQL);
$userLog->bindValue(':username', $username);
$userLog->execute();
$userLog->fetchAll();
#PLACE FOR SELECT DATA FROM SQL TO IMPORT TO SESSION
$sql = "SELECT * FROM users";
$stm = $connect->prepare($sql);
$stm->execute();
$row = $stm->fetch();
####################################################
if($userLog) {
$_SESSION['user_id'] = $row['user_id'];#id(mysql)
$_SESSION['username'] = $row['username'];#user(mysql)
$_SESSION['email'] = $row['email'];#email(mysql)
$_SESSION['f_name'] = $row['first_name'];#fname(mysql)
$_SESSION['l_name'] = $row['last_name'];#lname(mysql)
header('Location: index.php');
exit();
} else {
}
}
}
Sorry for bad english
I couldnt go deep to create a class! you need to check for classes.
I just corrected your code as much as I can, I used bindParam instead of bindValue.
I hope you are using pdo, it show you are :) Please put session_start(); on top of your page before everything else.
function userLog() {
global $connect;
if(isset($_POST['userLog'])) {
$username = trim($_POST['username']);
$password = trim($_POST['password']);
if(empty($username)) {
$_SESSION['message'] = 'Enter username';
header('Location: index.php');
exit();
} elseif (empty($password)) {
$_SESSION['message'] = 'Enter password';
header('Location: index.php');
exit();
}else{
$sql = "SELECT * FROM users WHERE username = :username";
if($stmt = $connect->prepare($sql)){
$stmt->bindParam(':username', $param_username, PDO::PARAM_STR);
$param_username = $username;
if($stmt->execute()){
$row = $stmt->fetch();
if($row['username'] === 1){
$hashed_password = $row['password'];
$email = $row['email'];
$name = $row['f_name'];
$lastname = $row['l_name'];
$id = intval($row['user_id']);
if(password_verify($password, $hashed_password)){
session_regenerate_id();
$_SESSION["loggedin"] = true;
$_SESSION['user_id'] = $id;
$_SESSION['username'] = $username;
$_SESSION['email'] = $email;
$_SESSION['f_name'] = $name;
$_SESSION['l_name'] = $lastname;
header('Location: index.php');
exit();
}else{
$_SESSION['message'] = 'wrong password';
}
}else{
$_SESSION['message'] = 'wrong username';
}
}else{
$_SESSION['message'] = 'User not found';
}
}else{
$_SESSION['message'] = 'Something went wrong';
}
}
}
}
I let you to do redirections to your error page
UPDATE : This is a simple class example, Search for proper way creating classes.
class userLog {
/** #var object $connect Copy of PDO connection */
private $connect;
/** #var object of the logged in user */
private $user;
/** #var string error msg */
private $msg;
public function __construct($connect) {
$this->connect = $connect;
}
public function login($username,$password){
$stmt = $this->connect->prepare('SELECT * FROM users WHERE username = ? ');
$stmt->execute([$username]);
$user = $stmt->fetch();
if(password_verify($password,$user['password'])){
$this->user = $user;
session_regenerate_id();
$_SESSION['user']['user_id'] = $user['user_id'];
$_SESSION['user']['fname'] = $user['fname'];
$_SESSION['user']['lname'] = $user['lname'];
$_SESSION['user']['email'] = $user['email'];
return true;
}else{
$this->msg = 'Invalid login information';
//you can change ajax response to session error
return false;
}
}
}
Usaqe : $handle = new userLog($connect);
Note this function requires ajax to return response.
Here you are not checking for any password so of course anyone can login, you should fix it like this:
$userSQL = "SELECT * FROM users WHERE username = :usr AND password = :pwd";
$userLog = $connect->prepare($userSQL);
$userLog->bindValue(':usr', $username);
$userLog->bindValue(':pwd', $password);
$userLog->execute();
$users = $userLog->fetchAll();
if(count($users) == 0) {
// fail here, no one to login
exit();
} elseif(count($users) > 1) {
// Found more than one user, this should not happen, maybe fail.
}
If this check pass the user is logged in and furthermore $users[0] holds your user information
ok so ive got password_hash working on one of my pages.
I'm wondering how would i apply password_verify to the following code:
function selectUser($conn, $username, $password)
{
$query = "SELECT username, password FROM login WHERE password = :password AND username = :username";
$stmt = $conn->prepare($query);
$stmt->bindValue(':username', $username);
$stmt->bindValue(':password', $password);
$stmt->execute();
if ($row = $stmt->fetch()) {
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
echo "Welcome, you are now logged in as " . $username;
return true;
}
else {
//echo "Your details were not found";
return false;
}
tried it myself and its been very confusing to me.
thank you
also got this:
if(!isset($_POST["Login"]))
{
header("Location:new-user.php");
}
$username=trim($_POST['username']);
$password=$_POST['password'];
$username= htmlspecialchars($username);
$validForm = true;
if (empty($_POST["username"]))
{
$validForm=false;
}
if (empty($_POST["password"]))
{
$validForm=false;
}
if (!$validForm) {
$error = "please ensure all fields are filled in";
include("add.php");
return false;
}
$conn=getConn();
$successLogin=selectUser($conn,$username,$password);
if($successLogin)
{
header( "Location: search.php" );
}else{
$error = "The details you have entered are incorrect";
include("add.php");
}
$conn=NULL; //close the connection
Update
also tried this: Knowing this doesnt work, tested with echo statements but still no luck
function hash_input() {
$password = "sfafgsd";
return $password = password_hash($_POST['password'], PASSWORD_BCRYPT);
}
function selectUser($conn, $username, $password)
{
$query = "SELECT password FROM login WHERE username = :username";
$stmt = $conn->prepare($query);
$stmt->bindValue(':username', $username);
$stmt->execute();
echo $username . " " . $password;
if ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo "WE MADE IT";
if(password_verify(hash_input($password), $row['password'])){
$_SESSION['username'] = $username;
echo "Welcome, you are now logged in as " . $username;
return true;
}
//echo "Your details were not found";
sleep(1);
return false;
}
else
{
//echo "Your details were not found";
return false;
}
}
The comments given by Mark cover the below exactly.
Order of events:
Send username to database and collect the hashed password from the row found.
run the password string given through password_verify to compare with the hashed value
return this result (true/false).
Celebrate. Have a coffeee or a tea.
There is no need to $_SESSION password data and this is a bad idea. Password data (hash or plaintext) should not be retained beyond this function call. If you do for some reason need to have a nonce value associated with this account/membership/login then this should be setup using a random string in its own column in the database.
Improved Function Code
function selectUser($conn, $username, $password)
{
$query = "SELECT password FROM login WHERE username = :username LIMIT 1";
$stmt = $conn->prepare($query);
$stmt->bindValue(':username', $username);
// $stmt->bindValue(':password', $password); NO Don't do this.
$stmt->execute();
if ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
if(password_verify($password,$row['password'])){
$_SESSION['username'] = $username;
// $_SESSION['password'] = $password; DO NOT DO THIS
echo "Welcome, you are now logged in as " . $username;
return true;
}
//bad password
//echo "Your details were not found";
sleep(1); // it can be a good idea to add a forced pause on
// password fail to discourage brute force cracking.
return false;
}
//echo "Your details were not found";
return false;
}
So I've made a login system here, it initiates a session, checks if the password is correct and then sets the session variables.
Here are a few things you might want to note:
It successfully logs in
There is no problem with the mysql connection
All files are places correctly in folders
There are no warnings or error messages
The MYSQL Table structure is correct and there are no errors in database
Note: all functions I'm about to define are in the same file 'functions.php'
Over here we have the session function
include_once("global_config.php");
include_once("db_connect.php");
function sec_session_start()
{
$session_name = 'sec_session_id';
$secure = SECURE;
$httponly = true;
if(ini_set('session.use_only_cookies', 1) === FALSE)
{
echo "Could not initiate a secure session";
exit;
}
$cookieparams = session_get_cookie_params();
session_set_cookie_params($cookieparams['lifetime'],$cookieparams['path'],$cookieparams['domain'],$secure,$httponly);
session_name($session_name);
session_start();
session_regenerate_id();
}
The global_config file define the mysql password, database, user and host and the db_connect file simply return the mysqli_connect to connect to the database.
And this over here is the login function
function login($user,$pass){
sec_session_start();
$link=linkit();
if(empty($user) || empty($pass) || !isset($user) || !isset($pass)){
echo "Error Code: 313, Please contact network administrator for more information";
exit;
}else{
$usercheck = "SELECT `id`,`username`,`password`,`salt` FROM `".LOGINTABLE."` WHERE `username`=? LIMIT 1";
if($stmt=$link->prepare($usercheck)){
$stmt->bind_param('s',$user);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id,$username,$realpassword,$salt);
$stmt->fetch();
$stmt->close();
if(empty($realpassword)){
echo 'Unrecognized Username, Please enter a valid username';
exit;
}else{
if($realpassword===$pass){
$_SESSION['username'] = $user;
$_SESSION['user_id'] = $id;
$_SESSION['login_string'] = hash('sha512',$pass);
return true;
}else{
echo "Invalid Password!";
exit;
}
}
}
}
}
The linkit() method is the one defined in db_connect.php which returns mysqli_connect. Also note that the script successfully makes it to setting the Session variable which means that it does return true.
NOW THE PROBLEM is this, when I'm checking for logged in status
function check_login()
{
if(isset($_SESSION['user_id']) &&
isset($_SESSION['login_string']) && isset($_SESSION['username']))
{
$user_id = $_SESSION['user_id'];
$username = $_SESSIOOO['username'];
$login_string = $_SESSION['login_string'];
$pwd_check = "SELECT `password` FROM `".LOGINTABLE."` WHERE `user_id`=? LIMIT 1";
if($stmt = linkit()->prepare($pwd_check))
{
$stmt->bind_param('s',$user_id);
$stmt->execute();
$stmt->bind_result($realpassword);
$stmt->fetch();
$stmt->close();
$hashedpass = hash('sha512',$realpassword);
if($login_string==$hashedpass){
return true;
}else{
return false;
}
}else{
return true;
}
}else{
return false;
}
}
AND FINALLY, this is WHERE I process my login script. Also note that there are no errors in POST methods or anything else. They all work fine.
This is in a separate php file and NOT in the functions.php
<?php
include_once '../includes/functions.php';
if(empty($_POST['loginuser']) || !isset($_POST['loginuser']) || !isset($_POST['id']) || empty($_POST['id']) || !isset($_POST['password']) || empty($_POST['password']))
{
echo "Error Code: 412, Please contact network administrator for more information";
exit;
}else{
if($_POST['loginuser']==="true")
{
$user = $_POST['id'];
$pass = $_POST['password'];
if(login($user,$pass)==true)
{
echo "Logged In!";
}else
{
echo "Failed to login, check your username or password";
}
}
}
?>
Additional Information :
The response I get is "Logged In"
Session is successfully creaated
PROBLEM: When I check for the login status, it returns false despite of having the session variables set.
In check_login you are hashing the password and then compare the unhashed password
function check_login()
{
if(isset($_SESSION['user_id']) &&
isset($_SESSION['login_string']) && isset($_SESSION['username']))
{
$user_id = $_SESSION['user_id'];
$username = $_SESSIOOO['username'];
$login_string = $_SESSION['login_string'];
$pwd_check = "SELECT `password` FROM `".LOGINTABLE."` WHERE `user_id`=? LIMIT 1";
if($stmt = linkit()->prepare($pwd_check))
{
$stmt->bind_param('s',$user_id);
$stmt->execute();
$stmt->bind_result($realpassword);
$stmt->fetch();
$stmt->close();
$hashedpass = hash('sha512',$realpassword);
if($login_string==$hashedpass ){
return true;
}else{
return false;
}
}else{
return true;
}
}else{
return false;
}
}