This question already has answers here:
How to use store and use session variables across pages?
(8 answers)
How can I get useful error messages in PHP?
(41 answers)
Closed 2 years ago.
I am creating a login system and I have completed the authentication and a user can log in successfully. However, I have tried checking for the correct session variables on other pages but even if a user hasn't logged in they can still access these pages.
authenticate.php
<?php
//Start session.
session_start();
//Connect to MySQL
$servername = "localhost";
$username = "root";
$password = "Turtle#98!";
$dbname = "login";
$conn = mysqli_connect($servername, $username, $password, $dbname);
//Check the connection
if (!$conn) {
die("Connection failed: " . mysqli_connect_error());
}
// Check if the data from the login form was submitted.
if ( !isset($_POST['username'], $_POST['password']) ) {
// Could not get the data that should have been sent.
exit('Please fill both the username and password fields!');
}
// Preparing the SQL statement will prevent SQL injection.
$stmt = mysqli_prepare($conn, ("SELECT password FROM users WHERE username=?"));
if ( !$stmt) {
die('mysqli error: ' .mysqli_error($conn));
}
//Bind input variables to prepared statement.
mysqli_stmt_bind_param($stmt, 's', $_POST['username']);
//Execute prepared statement.
mysqli_stmt_execute($stmt);
//Store the result to check if account exists.
mysqli_stmt_store_result($stmt);
//Make sure 'users' table is not empty.
if (mysqli_stmt_num_rows($stmt) > 0) {
//Bind password in table to stmt.
mysqli_stmt_bind_result($stmt, $password);
mysqli_stmt_fetch($stmt);
// Account exists so now to verify the password, as password stored is hashed.
if (password_verify($_POST['password'], $password)) {
// User logged in.
// Create sessions so we know the user is logged in.
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
//Redirect user to StudentEntry page after successful login.
header('Location: StudentEntry.php');
//echo 'Welcome ' . $_SESSION['name'] . '!';
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
session variable check on other page
session_start();
// If the user is not logged in redirect to the login page.
if (!isset($_SESSION['loggedin'])) {
header('Location: UserLogin.html');
exit;
}
Thanks
Related
I have created a website that has a basic registration and login system, I have pages that I only want admins to access.
My database for the accounts has a role column with 1 user assigned as admin and the other assigned as user
AUTHENTICATE.PHP
<?php
session_start();
// Change this to your connection info.
$DATABASE_HOST = 'localhost';
$DATABASE_USER = 'root';
$DATABASE_PASS = '';
$DATABASE_NAME = 'feedbackdb';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if ( mysqli_connect_errno() ) {
// If there is an error with the connection, stop the script and display the error.
exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// Now we check if the data from the login form was submitted, isset() will check if the data exists.
if ( !isset($_POST['username'], $_POST['password']) ) {
// Could not get the data that should have been sent.
exit('Please fill both the username and password fields!');
}
// Prepare our SQL, preparing the SQL statement will prevent SQL injection.
if ($stmt = $con->prepare('SELECT id, password FROM accounts WHERE username = ?')) {
// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
// Store the result so we can check if the account exists in the database.
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $password);
$stmt->fetch();
// Account exists, now we verify the password.
// Note: remember to use password_hash in your registration file to store the hashed passwords.
if (password_verify($_POST['password'], $password)) {
// Verification success! User has loggedin!
// Create sessions so we know the user is logged in, they basically act like cookies but remember the data on the server.
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
$_SESSION['admin'] = true/false;
header('location: home.php');
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
$stmt->close();
}
?>
And what I use to check:
<?php
session_start();
if(isset($_SESSION['admin'], $_SESSION['admin'])){
header('Location: index.php');
exit;
}
?>
that's the code I'm using in the page,
the problem I have is it doesn't matter who I log in as it always redirects, whereas I want the page to be accessible for admins but not users.
First, you need to alter your query to return the role column.
if ($stmt = $con->prepare('SELECT id, password, role FROM accounts WHERE username = ?'))
Next, you need to bind that value the same way you do $id and $password.
$stmt->bind_result($id, $password, $role);
Next, inside of your password_verify() block where you assign the other $_SESSION variables, set a role variable.
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
$_SESSION['role'] = $role;
Now, on any page you want, you can block access to anyone who isn't an admin.
if(empty($_SESSION['role']) || $_SESSION['role'] !== 'admin') {
//block user access
die("You do not have permission to view this page.");
}
If you want to show something on a page which is only visible to admins without blocking all users from the page entirely, you could do
if(!empty($_SESSION['role']) && $_SESSION['role'] == 'admin') {
echo "Only admins can see this text.";
}
Variable Cleanup
I recommend instead of creating multiple different session variable, you create a single user session variable containing an array of data you may need. I recommend this because it is cleaner, easier to manage, and easier to use later in your code.
Basically, replace all of your $_SESSION variable declarations with this:
$_SESSION['user'] = [
'loggedin' => true,
'name' => $_POST['username'],
'id' => $id,
'role' => $role
];
Then, to check if the user is an admin you would do something like this:
if(empty($_SESSION['user']) || $_SESSION['user']['role'] !== 'admin') {
//block user access
die("You do not have permission to view this page.");
}
And to show something for only admins without blocking all users from the page entirely:
if(!empty($_SESSION['user']) && $_SESSION['user']['role'] == 'admin') {
echo "Only admins can see this text.";
}
NOTE: Using MySQL Root user for website DB access is extremely unwise
and unsafe. Don't do it. Make a specific MySQL user only with limited
permissions on that data that they require
from Martin in the
comments.
So here is the deal, I have been following tutorials all day trying to resolve this issue I am having.
So far my webpage shows "Username invalid" , but I have confirmed in the inspector in chrome that it is infact passing the correct username and password to my login script (below) am I doing anything wrong?!
<?php
session_start();
// Change this to your connection info.
$DATABASE_HOST = 'db_ip';
$DATABASE_USER = 'db_user';
$DATABASE_PASS = 'db_pass';
$DATABASE_NAME = 'db_name';
// Try and connect using the info above.
$con = mysqli_connect($DATABASE_HOST, $DATABASE_USER, $DATABASE_PASS, $DATABASE_NAME);
if ( mysqli_connect_errno() ) {
// If there is an error with the connection, stop the script and display the error.
exit('Failed to connect to MySQL: ' . mysqli_connect_error());
}
// Now we check if the data from the login form was submitted, isset() will check if the data exists.
if ( !isset($_POST['username'], $_POST['password']) ) {
// Could not get the data that should have been sent.
exit('Please fill both the username and password fields!');
}
// Prepare our SQL, preparing the SQL statement will prevent SQL injection.
if ($stmt = $con->prepare("SELECT id, password FROM `accounts` WHERE username = '$username'")) {
// Bind parameters (s = string, i = int, b = blob, etc), in our case the username is a string so we use "s"
$stmt->execute();
// Store the result so we can check if the account exists in the database.
$stmt->store_result();
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $password);
$stmt->fetch();
// Account exists, now we verify the password.
// Note: remember to use password_hash in your registration file to store the hashed passwords.
if ($_POST['password'] === $password) {
// Verification success! User has loggedin!
// Create sessions so we know the user is logged in, they basically act like cookies but remember the data on the server.
session_regenerate_id();
$_SESSION['loggedin'] = TRUE;
$_SESSION['name'] = $_POST['username'];
$_SESSION['id'] = $id;
echo 'Welcome ' . $_SESSION['name'] . '!';
} else {
echo 'Incorrect password!';
}
} else {
echo 'Incorrect username!';
}
$stmt->close();
}
?>
I was able to resolve my issue with the following:
where I was defining $stmt I was using $username when it had not been defined yet, I changed this line
$con->prepare("SELECT id, password FROM `accounts` WHERE username = '$username'"))
to
$con->prepare('SELECT id, password FROM `accounts` WHERE username = ?'))
and added this above my execute statement:
$stmt->bind_result($id, $password);
I'm trying to create a login form which accesses details from a MySQL database and then redirects the user to another page. However Whenever I try to login using the correct credentials, I keep getting an incorrect password error. Can anyone see anything wrong with the following code?
<?php
// Initialize the session
session_start();
// Check if the user is already logged in, if yes then redirect to welcome page
if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){
header("location: index.php");
exit;
}
// Include config file
include "connection.php";
// Define variables and initialize with empty values
$username = $password = "";
$username_err = $password_err = "";
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
//find first name of logged in user
// Check if username is empty
if(empty(trim($_POST["username"]))){
$username_err = "Please enter username.";
} else{
$email = trim($_POST["username"]);
// Check if the password is empty
if(empty(trim($_POST["password"]))){
$password_err = "Please enter your password.";
} else{
$password = trim($_POST["password"]);
}
// Validate credentials
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT Email, Password FROM users WHERE Email = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_email);
// Set parameters
$param_email = $email;
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Store result
mysqli_stmt_store_result($stmt);
// Check if username exists, if yes then verify password
if(mysqli_stmt_num_rows($stmt) == 1){
// Bind result variables
mysqli_stmt_bind_result($stmt, $email, $hashed_password);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
// if the password is correct, begin a new session
session_start();
// allocate values to session variables
$_SESSION["loggedin"] = true;
$_SESSION["username"] = $email;
// Redirect user to welcome page
header("location: index.php");
} else{
// Display error message for incorrect password
$message = "Incorrect password, please try again";
echo "<script>
alert('$message');
window.location.href='login.php';
</script>";
exit;
}
}
} else{
// Display an error message if username doesn't exist
$message = "Incorrect username, please try again";
echo "<script>
alert('$message');
window.location.href='login.php';
</script>";
exit;
}
} else{
echo "Something went wrong. Please try again later.";
}
} else {
//prevent SQL Injection
die("Error : " . mysqli_error($conn));
}
// Close statement
mysqli_stmt_close($stmt);
}
// Close connection
mysqli_close($link);
}
}
?>
Any help would be appreciated.
This might be me being blind (or that this is just a snippet), but you're not actually opening your connection to MySQL so $link will be null at the point you try to prepare your statement. (Sorry I didn't post this as a comment, I'm too new to this)
I am building a study planner that features just a single welcome area, after logging in. I am currently trying to obtain the user ID of the currently logged in user for use in an SQL update query in this welcome area, as well as the user’s first name for use in the welcome message.
I have tried putting $_SESSION['user_id'] = userid; and $_SESSION['user_firstname'] = firstname; after $_SESSION['login_user'] = $username; ($_SESSION['login_user'] = $username; works fine by the way) but upon logging into the page, I get these errors: Notice: Use of undefined constant userid - assumed 'userid' in C:\wamp64\www\justread\session.php on line 11 and Notice: Use of undefined constant firstname - assumed 'firstname' in C:\wamp64\www\justread\session.php on line 12.
Now, I know the errors want me to do some sort of initialisation for ‘userid’ and ‘firstname’ first before using them to set up a session variable but I am not sure how to go about it, so I am wondering if someone could help me, please.
Thanking you in advance.
I can post more codes if required but the codes I believe are concerned are:
login.php:
<?php
// Start session
session_start();
// Variable to store error message
$error ="";
// If the login form (Note that the 'submit' refers to the 'name' attribute of the login form) has been submitted...
if (isset($_POST['submit'])) {
// If username or password is not provided...
if (empty($_POST['username']) || empty($_POST['password'])) {
// ...tell user that login details are invalid.
$error = "Please fill in both your username and your password";
// Else...
} else {
// ...put the provided username and password in variables $username and $password, respectively
$username = $_POST['username'];
$password = $_POST['password'];
// Establish connection to the server
$mysqli = mysqli_connect("localhost", "root", "");
// set up measures to counter potential MySQL injections
$username = stripslashes($username);
$password = stripslashes($password);
$username = mysqli_real_escape_string($mysqli, $username);
$password = mysqli_real_escape_string($mysqli, $password);
// Select Database
$db = mysqli_select_db($mysqli, "p00702");
// SQL query to fetch information of registerd users and find user match.
$query = mysqli_query($mysqli, "SELECT * from logins WHERE password='$password' AND username='$username'");
// Return the number of rows of the query result and put it in $rows variable
$rows = mysqli_num_rows($query);
// If rows are equal to one...
if ($rows == 1) {
unset($_SESSION['error']);
// Initialize session with the username of the user...
$_SESSION['login_user'] = $username;
// Set the user ID of the user
$_SESSION['user_id'] = userid;
// Set the user first name of the user
$_SESSION['user_firstname'] = firstname;
// ...and redirect to the homepage.
header("Location: welcome.php");
// Make sure that codes below do not execut upon redirection.
exit;
// Else,
} else {
// and tell user that the login credentials are invalid.
$error = "Your username or password is invalid";
$_SESSION['error'] = $error;
// redirect user to the home page (index.php)
header("Location: index.php");
}
// ...and close connection
mysqli_close($mysqli);
}
}
session.php
<?php
// Establish connection to the server
$mysqli = mysqli_connect("localhost", "root", "");
// Selecting Database
$db = mysqli_select_db($mysqli, "p00702");
// Starting session
session_start();
// Storing Session
$user_check = $_SESSION['login_user'];
$_SESSION['user_id'] = userid;
$_SESSION['user_firstname'] = firstname;
// Test to see the content of the global session variable
print_r($_SESSION);
// SQL Query To Fetch Complete Information Of User
$ses_sql = mysqli_query($mysqli, "SELECT username FROM logins WHERE username='$user_check'");
$row = mysqli_fetch_assoc($ses_sql);
$login_session = $row['username'];
if (!isset($login_session)) {
// Closing Connection
mysqli_close($mysqli);
// Redirecting To Home Page
header('Location: index.php');
// Make sure that codes below do not execut upon redirection.
exit;
}
In PHP, variable name starts with '$' sign. Also, in login.php, you have to fetch the data using mysqli_fetch_row or any similar function. Am assuming you are redirecting to session.php after logging in. In that case, you don't have to assign anything to the session variables. It will be there already. All you have to do is to access it.
login.php
<?php
// Start session
session_start();
// Variable to store error message
$error ="";
// If the login form (Note that the 'submit' refers to the 'name' attribute of the login form) has been submitted...
if (isset($_POST['submit'])) {
// If username or password is not provided...
if (empty($_POST['username']) || empty($_POST['password'])) {
// ...tell user that login details are invalid.
$error = "Please fill in both your username and your password";
// Else...
} else {
// ...put the provided username and password in variables $username and $password, respectively
$username = $_POST['username'];
$password = $_POST['password'];
// Establish connection to the server
$mysqli = mysqli_connect("localhost", "root", "");
// set up measures to counter potential MySQL injections
$username = stripslashes($username);
$password = stripslashes($password);
$username = mysqli_real_escape_string($mysqli, $username);
$password = mysqli_real_escape_string($mysqli, $password);
// Select Database
$db = mysqli_select_db($mysqli, "p00702");
// SQL query to fetch information of registerd users and find user match.
$query = mysqli_query($mysqli, "SELECT * from logins WHERE password='$password' AND username='$username'");
// Return the number of rows of the query result and put it in $rows variable
$rows = mysqli_num_rows($query);
// If rows are equal to one...
if ($rows == 1) {
$row = mysql_fetch_object($query);
unset($_SESSION['error']);
// Initialize session with the username of the user...
$_SESSION['login_user'] = $username;
// Set the user ID of the user
$_SESSION['user_id'] = $row->userid;
// Set the user first name of the user
$_SESSION['user_firstname'] = $row->firstname;
// ...and redirect to the homepage.
header("Location: welcome.php");
// Make sure that codes below do not execut upon redirection.
exit;
// Else,
} else {
// and tell user that the login credentials are invalid.
$error = "Your username or password is invalid";
$_SESSION['error'] = $error;
// redirect user to the home page (index.php)
header("Location: index.php");
}
// ...and close connection
mysqli_close($mysqli);
}
}
session.php
<?php
// Establish connection to the server
$mysqli = mysqli_connect("localhost", "root", "");
// Selecting Database
$db = mysqli_select_db($mysqli, "p00702");
// Starting session
session_start();
if (!isset($_SESSION['user_id'])) {
// Closing Connection
// Redirecting To Home Page
header('Location: index.php');
// Make sure that codes below do not execut upon redirection.
exit;
}
print_r($_SESSION);
Also, move the connection part to a seperate file and include it in all scripts, so that when your credentials change, you don't have to change it in all the files.
I am trying to find how to check if a variable called active is equal to 1. My attempt at the function is below:
function login($email, $password, $mysqli) {
// Using prepared statements means that SQL injection is not possible.
if ($stmt = $mysqli->prepare("SELECT id, username, password, salt, active
FROM members
WHERE email = ? LIMIT 1")) {
$stmt->bind_param('s', $email); // Bind "$email" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($user_id, $username, $db_password, $salt, $active);
$stmt->fetch();
// hash the password with the unique salt.
$password = hash('sha512', $password . $salt);
if ($stmt->num_rows == 1) {
// If the user exists we check if the account is locked
// from too many login attempts
if (checkbrute($user_id, $mysqli) == true) {
// Account is locked
// Send an email to user saying their account is locked
return false;
} else {
// Check if the password in the database matches
// the password the user submitted.
if ($db_password == $password) {
// Password is correct!
// Get the user-agent string of the user.
$user_browser = $_SERVER['HTTP_USER_AGENT'];
// XSS protection as we might print this value
$user_id = preg_replace("/[^0-9]+/", "", $user_id);
$_SESSION['user_id'] = $user_id;
// XSS protection as we might print this value
$username = preg_replace("/[^a-zA-Z0-9_\-]+/", "", $username);
$_SESSION['username'] = $username;
$_SESSION['login_string'] = hash('sha512', $password . $user_browser);
} else {
// Password is not correct
// We record this attempt in the database
$now = time();
if (!$mysqli->query("INSERT INTO login_attempts(user_id, time)
VALUES ('$user_id', '$now')")) {
header("Location: ../error?err=Database error: login_attempts");
exit();
}
return false;
}
}
} else {
// No user exists.
return false;
}
} else {
// Could not create a prepared statement
header("Location: ../error?err=Database error: cannot prepare statement");
exit();
}
}
I assume that where I added active to the $mysqli->prepare statement is correct.
What I want to do is if the user got their password correct I would query the MySQL table to see if his account is active(1) or not active(0). If it is set to 0 it logs in with no error. However in my process_login.php file it logs the user in if it is (0) but with index.php?err=1
<?php
include_once 'db_connect.php';
include_once 'functions.php';
sec_session_start(); // Our custom secure way of starting a PHP session.
if (isset($_POST['email'], $_POST['p'])) {
$email = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);
$password = $_POST['p']; // The hashed password.
if (login($email, $password, $mysqli) == true) {
// Login success
header("Location: ../protected_page.php");
exit();
} else {
// Login failed
header('Location: ../index.php?error=1');
echo $active;
exit();
}
} else {
// The correct POST variables were not sent to this page.
header('Location: ../error.php?err=Could not process login');
exit();
}
When I try to echo the variable $active it returns nothing.
Any help is appreciated in advance.
Posting this as a community wiki; I don't want rep for it, nor should there be any made from it.
A: You did not follow that tutorial exactly as it was written.
http://www.wikihow.com/Create-a-Secure-Login-Script-in-PHP-and-MySQL
since it is obvious that that is where that code comes from; I know it all too well.
You modified some parts of the code and left some out also.
Go back to the tutorial, and follow it " to a T ". You may also have to clear out your present hashes and start over.
Make sure that the table creation was done exactly as shown. If you failed to make the right columns and their proper lengths, then that will fail "silently" on you.
Consult the comments I left under the question also.