So I've copied a sign-up form and login form from TutorialRepublic and when it didn't work I added some alerts to figure out what bit of code was not being run.
I ended up finding out that the mysqli_prepare portion was being completely skipped over:
$sql = "SELECT id, username, password FROM acccounts WHERE username = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_username);
echo "<script type='text/javascript'>alert('yes');</script>";
// Set parameters
$param_username = $username;
// 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, $id, $username, $hashed_password);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: index.php");
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was not valid.";
}
}
} else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
// Close statement
mysqli_stmt_close($stmt);
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
else{
echo "<script type='text/javascript'>alert('error');</script>";
}
I know it's not the best to just take someone elses tutorial code and use it word for word, but I really just need this done. I'm pretty new to both PHP and MySQL, so I have no idea where to even begin trying to debug.
Okay, so essentially I just had to debug better. After help from two users in the comments, I was able to track down the errors.
I had already made and else statement for the alert to say that the mysqli_prepare had been skipped. In that else statement, I should have added echo mysqli_error ($link); as that will output the error info.
Related
This question already has answers here:
How to use PHP's password_hash to hash and verify passwords
(5 answers)
Closed 1 year ago.
I can't fix it yet and I don't know what's the problem is. I'm using it on xampp. I changed in my register.php the hash to sha256. Now if I'm trying to login with that's password and username which I registered, it says the username and password is wrong.
That's my login.php
if(empty($username_err) && empty($password_err)){
// Prepare a select statement
$sql = "SELECT id, username, password FROM users WHERE username = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_username);
// Set parameters
$param_username = $username;
// 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, $id, $username, $hashed_password);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: welcome.php");
} else{
// Password is not valid, display a generic error message
$login_err = "Invalid username or password.";
}
}
} else{
// Username doesn't exist, display a generic error message
$login_err = "Invalid username or password.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
// Close statement
mysqli_stmt_close($stmt);
}
}
// Close connection
mysqli_close($link);
That's my register.php what I only changed.
if(empty($username_err) && empty($password_err) && empty($confirm_password_err)){
// Prepare an insert statement
$sql = "INSERT INTO users (username, password) VALUES (?, ?)";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "ss", $param_username, $param_password);
// Set parameters
$param_username = $username;
$param_password = hash("sha256" , $_POST['password']); // Creates a password hash //<------------------THAT IS CHANGED
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Redirect to login page
header("location: login.php");
} else{
echo "Oops! Something went wrong. Please try again later.";
}
// Close statement
mysqli_stmt_close($stmt);
}
}
// Close connection
mysqli_close($link);
}
That´s because your plain password will never match a SHA256 encrypted text
You may try to convert your plain password again to sha256 and compare it, but it´s a bad practice and like Lawrence said, you shouldn't really be storing passwords in that format
password_verify works with password_hash where you provide your plain password and the hash algo see documentation here
I am setting up a new website with registration and login forms. As a beginner I am usting mostly part of codes I find online and in books. I have finished registration form and it works perfectly, but now I have a problem with a login form, because all codes that I can find are based on hashed password and the login form I have to build does not need it. Can you help to convert the script I have now into script that will work without any password (instead of a password it just need a 6 digital number which is not hashed).
I tried check_login, but it did not work.
$sql = "SELECT id, email, pin FROM users WHERE email = ?";
if($stmt = $mysqli->prepare($sql)){
// Bind variables to the prepared statement as parameters
$stmt->bind_param("s", $param_email);
// Set parameters
$param_email = $email;
// Attempt to execute the prepared statement
if($stmt->execute()){
// Store result
$stmt->store_result();
// Check if username exists, if yes then verify password
if($stmt->num_rows == 1){
// Bind result variables
$stmt->bind_result($id, $username, $numerpin);
if($stmt->fetch()){
if($stmt->num_rows == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["email"] = $email;
// Redirect user to welcome page
header("location: dashboard.php");
} else{
// Display an error message if password is not valid
$numerpin_err = "The password you entered was not valid.";
}
}
} else{
// Display an error message if username doesn't exist
$email_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
You have this query:
"SELECT id, email, pin FROM users WHERE email = ?"
You are checking for the email to be correct. You could change it to
"SELECT id, email, pin FROM users WHERE email = ? and pin = ?"
of course, passing pin as well. Also, your error message is misleading:
if($stmt->num_rows == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["email"] = $email;
// Redirect user to welcome page
header("location: dashboard.php");
} else{
// Display an error message if password is not valid
$numerpin_err = "The password you entered was not valid.";
}
what if there are multiple records with the very same email? In that case it will say that password is incorrect, without checking its actual value. It would be much more reliable to get the record(s) by email and pin, loop the results and when a match is found, then create a session. If there is no match, then error.
As others suggested. The best approach is to use hash password but since you do not want that. you can go ahead with this. Try the code below
<?php
$mysqli = new mysqli('localhost', 'your username', 'your password', 'your db name');
if($mysqli->connect_error){
echo "cannot connect to database";
}
// assuming your post variable is set as follows
$email = $_POST['email'];
$pin = $_POST['pin'];
$stmt = $mysqli->prepare("SELECT id, email, pin FROM users WHERE email = ? AND pin = ?");
/* i is for integer and s is for string. I suspect that your pin must be integer so I set the bind to i
*/
$stmt->bind_param("si", $email, $pin);
if($stmt->execute()){
$stmt->store_result();
$result = $stmt->get_result();
$num_rows = $result->num_rows;
}
if($num_rows == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["email"] = $email;
// Redirect user to welcome page
header("location: dashboard.php");
}else{
echo "Error: Either Email or Pin number is wrong";
}
?>
So i have a full code from an online tutorial and unfortunately when they provide the code there are certain areas which i have no idea what to put in. I know this could be very basic, but to people who don't know much about sql and php codes, they too will have some difficulty figuring out the basics.
Alot of people put the hard questions but never the simple basic questions that starters like me struggle to understand.
Here is the a link! where i got the information from.
I've tried going on google and going through stackoverflow, and webdevtrick but all the questions or concerns the people have are harder solving problems than the basic one i have.
Validate credentials
// Prepare a select statement
$sql = "SELECT id, username, password FROM users WHERE username = ?";
So i've tried to put a 1, 0, and i've tried putting 'username' in the question mark area but no luck. All it backfires me with is Oops! Something went wrong. Please try again later.
CODE AFTER THE VALIDATE CREDENTIALS
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_username);
// Set parameters
$param_username = $username;
// 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, $id, $username, $hashed_password);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: welcome.php");
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was not valid.";
}
}
} else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// Close connection
mysqli_close($link);
}
I bet it's so basic, but i'm hoping that if someone else who is also having difficulty with this will help them and understand what they should put in that statement. Thank you for the help, and if you need more information please let me know.
THANK YOU!
EDIT FOR THE PERSON WHO WANTED TO SEE THE WHOLE CODE
// Initialize the session
session_start();
// Check if the user is already logged in, if yes then redirect him to welcome page
if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){
header("location: welcome.php");
exit;
}
// Include config file
require_once "config.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"){
// Check if username is empty
if(empty(trim($_POST["username"]))){
$username_err = "Please enter username.";
} else{
$username = trim($_POST["username"]);
}
// Check if 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 id, username, password FROM users WHERE username = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Set parameters
$param_username = $username;
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_username);
// 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, $id, $username, $hashed_password);
if(mysqli_stmt_fetch($stmt)){
if(password_verify($password, $hashed_password)){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirect user to welcome page
header("location: welcome.php");
} else{
// Display an error message if password is not valid
$password_err = "The password you entered was not valid.";
}
}
} else{
// Display an error message if username doesn't exist
$username_err = "No account found with that username.";
}
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// Close connection
mysqli_close($link);
}
?>```
You don't put anything in place of the question mark; the question mark is meant to be there. The next line, mysqli_stmt_bind_param() replaces the question mark with $param_username programatically.
You will, however, need to assign something to $param_username before attempting to use it in this statement:
$param_username = 'name';
$sql = "SELECT id, username, password FROM users WHERE username = ?";
$stmt = mysqli_prepare($link, $sql)
mysqli_stmt_bind_param($stmt, "s", $param_username);
mysqli_stmt_execute($stmt);
The above will ultimately query SELECT id, username, password FROM users WHERE username = name.
In your (updated) example above, you set $param_username as $username, and $username as trim($_POST["username"]). If there is not a name field of username on an <input> in a <form> in the referring page, this value will be empty. Make sure to check for the presence of both $username and $password with:
if(
isset($_POST["username"]) && !empty($_POST["username"]) &&
isset($_POST["password"]) && !empty($_POST["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)
Just getting to grips with SQL and PHP and trying to build a simple user account system - with a forgotten password email link.
I have a script below that I am trying to use to update the password of a user. They receive an email with a link. The link looks like this: http://localhost:8887/email-password-reset.php?id=1.
I know this is unsafe and easily hackable! I am planning on using a randomly generated string of numbers, once I get this working!
I am trying to user the $_GET function to get the id. However I don't believe that the $_GET["id"] is getting passed to the $param_id variable.
I'm new to this so unsure how to rectify it!
How can I get this set the param_id to the $_GET Value?
At least that what I think the issue is from the error in the console (Undefined variable: param_id!) Thanks in advance!
<?php
//session_start();
require_once "config.php";
// Define variables and initialize with empty values
$new_password = $confirm_password = "";
$new_password_err = $confirm_password_err = "";
$param_id = '';
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Validate new password
if(empty(trim($_POST["new_password"]))){
$new_password_err = "Please enter the new password.";
} elseif(strlen(trim($_POST["new_password"])) < 6){
$new_password_err = "Password must have atleast 6 characters.";
} else{
$new_password = trim($_POST["new_password"]);
}
// Validate confirm password
if(empty(trim($_POST["confirm_password"]))){
$confirm_password_err = "Please confirm the password.";
} else{
$confirm_password = trim($_POST["confirm_password"]);
if(empty($new_password_err) && ($new_password != $confirm_password)){
$confirm_password_err = "Password did not match.";
}
}
// Check input errors before updating the database
if(empty($new_password_err) && empty($confirm_password_err)){
// Prepare an update statement
$sql = "UPDATE users SET password = ? WHERE id = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "si", $param_password, $param_id);
// Set parameters
$param_password = password_hash($new_password, PASSWORD_DEFAULT);
$param_id = (isset($_GET['id']) ? $_GET['id'] : '');
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Password updated successfully. Destroy the session, and redirect to login page
session_destroy();
header("location: login.php");
exit();
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// Close connection
mysqli_close($link);
}
?>
Cursory glance:
It's only going into your if if it's a POST type, by definition it'll be a GET type. You may need to remove/change that.
Secondly, you're building the query using $param_id before you assign $param_id to the GET variable.
If the only place, and it seems so, you're setting $param_id why not just declare it in the first line where you declare it as ''?
They receive an email with a link. The link looks like this: http://localhost:8887/email-password-reset.php?id=1
I assume if user click the link there will be a "new password" form. Then the form post the data to some url that contain the sciprt you use. To use $_GET['id'] you need make sure the url on the form ( maybe looks like action="http://localhost:8887/process.php") have GET parameter. So it's gonna looks like action="http://localhost:8887/process.php?id=1"
And the error Undefined variable: param_id! is because you use param_id before declare it. So, it's suppose looks like:
if($stmt = mysqli_prepare($link, $sql)){
// Set parameters
$param_password = password_hash($new_password, PASSWORD_DEFAULT);
$param_id = (isset($_GET['id']) ? $_GET['id'] : '');
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "si", $param_password, $param_id);
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Password updated successfully. Destroy the session, and redirect to login page
session_destroy();
header("location: login.php");
exit();
} else{
echo "Oops! Something went wrong. Please try again later.";
}