Retaining the $_GET url in the link when the user returns to the same page.in mysql php - php

When the user reset the password by sending their email id. The mail which they receive, is something like this.
Email
http://localhost/folder/folder/reset.php?email=foobar#foo.com&hash=07c5807d0d927
When the above link is clicked, the user fills the New password and Confirm password. We are getting the email and the has from the url. The code below.
reset.php
if( isset($_GET['email']) && !empty($_GET['email']) AND isset($_GET['hash']) && !empty($_GET['hash']) ) {
$email = $con->escape_string($_GET['email']);
$hash = $con->escape_string($_GET['hash']);
$result = $con->query("SELECT * FROM users WHERE email='$email' AND hash='$hash'");
if ( $result->num_rows == 0 ) {
$_SESSION['message'] = "Invalid URL for password reset!";
header("location: ../error.php");
}
}
else {
$_SESSION['message'] = "Verification failed, try again!";
header("location: ../error.php");
}
<!-- form goes here -->
We are using the code below to check the matching password.
resetpassword.php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Make sure the two passwords match
if ( $_POST['newpassword'] == $_POST['confirmpassword'] ) {
$new_password = password_hash($_POST['newpassword'], PASSWORD_BCRYPT);
// We get $_POST['email'] and $_POST['hash'] from the hidden input field of reset.php form
$email = $con->escape_string($_POST['email']);
$hash = $con->escape_string($_POST['hash']);
$sql = "UPDATE users SET password='$new_password', hash='$hash' WHERE email='$email'";
if ( $con->query($sql) ) {
$_SESSION['message'] = "Your password has been reset successfully! <a href='login.php'>Login</a>";
header("location: ../success.php");
}
}
else {
$_SESSION['message'] = "Passwords did not match, try again!";
header("location: ../reset.php");
}
}
Now the problem is here. If the users password did not match they goes to reset.php page and when they need to come back to to try again again. When that happens how do we get their email and hash back.
else {
$_SESSION['message'] = "Passwords did not match, try again!";
header("location: ../reset.php");
}
This is what we get, when they come back.
http://localhost/folder/folder/reset.php

Using sessions is your best option here.
Currently the code has another problem which you might want to avoid. Your user can go to resetpassword.php page with ANY email and reset the password for that email, which would result in a very unpleasant security issue.
The proper way of doing what you intend to do would be
reset.php
<?php
$email = array_key_exists('email', $_GET) && !empty($_GET['email']) ? $_GET['email'] : null;
$hash = array_key_exists('hash', $_GET) && !empty($_GET['hash']) ? $_GET['hash'] : null;
session_start();
if( $email !== null && $hash !== null) {
$email = $con->escape_string($email);
$hash = $con->escape_string($hash);
$result = $con->query("SELECT * FROM users WHERE email='$email' AND hash='$hash'");
if ( $result->num_rows == 0 ) {
$_SESSION['message'] = "Invalid URL for password reset!";
header("location: ../error.php");
} else {
$_SESSION['reset_email'] = $email;
$_SESSION['reset_hash'] = $hash;
// do redirect to your new password page or smth
}
}
else {
$_SESSION['message'] = "Verification failed, try again!";
header("location: ../error.php");
}
and resetpassword.php
<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST' && array_key_exists('reset_email', $_SESSION) && !empty($_SESSION['reset_email'])) {
// Make sure the two passwords match
if ( $_POST['newpassword'] == $_POST['confirmpassword'] ) {
$new_password = password_hash($_POST['newpassword'], PASSWORD_BCRYPT);
// not sure why you would need to update password reset hash there, so i removed it
$sql = "UPDATE users SET password='$new_password' WHERE email='{$_SESSION['reset_email']}'";
if ( $con->query($sql) ) {
$_SESSION['message'] = "Your password has been reset successfully! <a href='login.php'>Login</a>";
$_SESSION['reset_email'] = null;
$_SESSION['reset_hash'] = null;
header("location: ../success.php");
} else {
// error probably a good thing here (for the user)
$_SESSION['message'] = "Verification failed, try again!";
header("location: ../error.php");
}
}
else {
$_SESSION['message'] = "Passwords did not match, try again!";
header("location: ../reset.php?email={$_SESSION['reset_email']}&hash={$_SESSION['reset_hash']}");
}
}

Related

Check for duplicate user from MySQL database [duplicate]

This question already has answers here:
How to check if a row exists in MySQL? (i.e. check if username or email exists in MySQL)
(4 answers)
Closed 5 years ago.
I would like to check for duplicates in a MySQL database when registering an user.
If the user exists display an error to that effect, else sign up.
I know there's a few questions like this but I found it hard to paste any of them into my code.
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//two passwords are the same
if($_POST['password'] == $_POST['confirmedpassword']) {
$username = $mysqli->real_escape_string($_POST['username']);
$password = md5($_POST['password']);
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
$sql = "INSERT INTO members(username, password)"
. "VALUES ('$username','$password')";
//if query is successful redirect to login.php
if ($mysqli->query($sql) === true)
$_SESSION['message'] = 'Success';
header("location: login.php");
} else {
$_SESSION['message'] = "User couldnt be added";
}
} else {
$_SESSION['message'] = "Passwords dont match";
}
}
I added some salt to your md5 password to make it seem more secure, but actually this solution is not secure either. To encrypt passwords in PHP it is advisable to use the password_hash() function like this:
$pass = password_hash($password, PASSWORD_BCRYPT);
password_hash() creates a new password hash using a strong one-way hashing algorithm.
and later test it with password_verify():
password_verify ( $passToTest , $knownPasswordHash );
more the functions here: http://php.net/password-hash, http://php.net/password-verify.
Also, since you are using MySQLi consider using prepared statements, or at least properly filter your input data before applying it to the database.
More on prepared statements: http://php.net/prepared-statements.
I added a select statement to check if the user already exists in the table prior to adding the user to the database.
When using header() to change page location put exit() or die() in the next line of code if you want to exit immediately and don't want other code to execute.
Here is your code with the addition of the select statement:
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
//two passwords are the same
if($_POST['password'] == $_POST['confirmedpassword'])
{
$username = $mysqli->real_escape_string($_POST['username']);
// You might consider using salt when storing passwords like this
$salt = 'aNiceDay';
$password = md5(md5($_POST['password'].$salt).$salt);
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
$sql = "SELECT `username` FROM members WHERE `username` = '".$username."'";
$result = $mysqli->query($sql);
if(mysqli_num_rows($result) > 0)
{
echo 'User exists.';
// Do something.
}
else
{
$sql = "INSERT INTO members(username, password) VALUES ('".$username."','".$password."')";
if($mysqli->query($sql) === true)
{
$_SESSION['message'] = 'Success';
header("location: login.php");
// Important to put exit() after header so other code
// doesn't get executed.
exit();
}
else
{
$_SESSION['message'] = "User couldn't be added";
echo "User couldn't be added.";
}
}
}
else
{
$_SESSION['message'] = "Passwords dont match";
}
}
?>
So you can check that the user exists or not.
if ($_SERVER['REQUEST_METHOD'] == 'POST'){
//two passwords are the same
if($_POST['password'] == $_POST['confirmedpassword']) {
$username = $mysqli->real_escape_string($_POST['username']);
$password = md5($_POST['password']);
$_SESSION['username'] = $username;
$_SESSION['password'] = $password;
//Check user
$CheckUserIsExist = mysqli->query("SELECT uid FROM members WHERE username='$username'");
if(mysqli_num_rows($CheckUserIsExist)==0 ){
$sql = "INSERT INTO members(username, password)"
. "VALUES ('$username','$password')";
//if query is successful redirect to login.php
if($mysqli->query($sql) === true)
$_SESSION['message'] = 'Success';
header("location: login.php");
}
} else{
echo 'This username is already in use. Please use different username';
}
else{
$_SESSION['message'] = "User couldn't be added";
}
}
else{
$_SESSION['message'] = "Passwords don't match";
}

header function not redirecting to home.php, why?

Here i am using header function to redirect to home.php after login, but header function is not redirecting to that page. Even when i run same code on my local computer it works fine.
<?php
ob_start();
session_start();
require_once 'phpconnection.php';
// it will never let you open index(login) page if session is set
if ( isset($_SESSION['user'])!="" ) {
header("Location:home.php");
exit;
}
$error = false;
if( isset($_POST['btn-logIn']) ) {
// prevent sql injections/ clear user invalid inputs
$email = trim($_POST['email']);
$email = strip_tags($email);
$email = htmlspecialchars($email);
$pass = trim($_POST['password']);
$pass = strip_tags($pass);
$pass = htmlspecialchars($pass);
// prevent sql injections / clear user invalid inputs
if ( !filter_var($email,FILTER_VALIDATE_EMAIL) ) {
$error = true;
$errMsg = "Please enter valid email address.";
}
// if there's no error, continue to login
if (!$error) {
$res=mysql_query("SELECT userId, userfName, userlName,userPassword FROM userdata WHERE userEmail='$email'");
$row=mysql_fetch_array($res);
$count = mysql_num_rows($res); // if uname/pass correct it returns must be 1 row
if( $count == 1 && $row['userPassword']==$pass ) {
$_SESSION['user'] = $row['userId'];
header("Location:home.php");
} else {
$errMsg = "Try again...";
}
}
}
?>
You do not need the !="" on line 5 because isset() already checks for existence. Either its there or its not.
if (isset($_SESSION['user'])){
header("Location: home.php");
exit;
} else {
echo "something here";
}
You can use !isset() to get the opposite result as well.
Try your code with this code,
<?php
ob_start();
session_start();
if ( isset($_SESSION['user'])!="" ) {
header("Location:home.php");
exit;
}
require_once 'phpconnection.php';
// it will never let you open index(login) page if session is set
?>

PHP can't determine whether user is logged in or not

I'm creating a system that the header will show 'login' if the user is not logged in, and if they are, it'll display logout. I've simplified it for now, just showing if the user is logged in or not. With "Login!" meaning they need to login, and "Welcome!" if they are logged in. I used the PHP Code Checker website (https://phpcodechecker.com/) and it couldn't find any errors. I also searched stackoverflow, and everyone else's seems to work.
<?php
ob_start();
session_start();
require_once 'dbconnect.php';
if( !isset($_SESSION['user']) ) {
echo "Login!";
} else {
echo "Welcome!";
}
?>
is the code that checks if the user is logged in or not.
My login page works for EVERYTHING else, for my homepage is shows that the user is logged in, but here is the code anyway. (This is only the PHP code, there is HTML for the submit button, ect.)
<?php
ob_start();
session_start();
require_once 'dbconnect.php';
// it will never let you open index(login) page if session is set
if ( isset($_SESSION['user'])!="" ) {
header("Location: index.php");
exit;
}
$error = false;
if( isset($_POST['btn-login']) ) {
// prevent sql injections/ clear user invalid inputs
$email = trim($_POST['email']);
$email = strip_tags($email);
$email = htmlspecialchars($email);
$name = trim($_POST['name']);
$name = strip_tags($name);
$name = htmlspecialchars($name);
$pass = trim($_POST['pass']);
$pass = strip_tags($pass);
$pass = htmlspecialchars($pass);
// prevent sql injections / clear user invalid inputs
if(empty($name)){
$error = true;
$nameError = "Please enter your username.";
}
if(empty($pass)){
$error = true;
$passError = "Please enter your password.";
}
// if there's no error, continue to login
if (!$error) {
$password = hash('sha256', $pass); // password hashing using SHA256
$res=mysql_query("SELECT userId, userEmail, userPass FROM users WHERE
userName='$name'");
$row=mysql_fetch_array($res);
$count = mysql_num_rows($res); // if email/pass correct it returns must be
1 row
if( $count == 1 && $row['userPass']==$password ) {
$_SESSION['user'] = $row['userId'];
header("Location: dashboard.php");
} else {
$errMSG = "Incorrect Credentials, Try again...";
}
}
}
?>
It connects to the database fine, and i'm certain there is no problems with the database, since it works on my other pages.
I've spent a long-while trying to figure this out, and can't.
Thanks!
In your code
if ( isset($_SESSION['user'])!="" ) {
you are comparing true|false != ""
change it to if (isset($_SESSION['user'])) {
or
if (isset($_SESSION['user']) && ($_SESSION['user']!="")) {

password_verify($_POST['password'], $hash) always return false password

My question is, when I try to log in with correct password, it still display the error message "You have entered wrong password, try again!".(Register works fine, the part checking if user already exist works fine) Here is the code:
register.php (works):
<?php
include('db_conn.php'); //db connection
session_start();
/* Registration process, inserts user info into the database
and sends account confirmation email message
*/
$_SESSION['email'] = $_POST['email'];
$_SESSION['full_name'] = $_POST['name'];
// Escape all $_POST variables to protect against SQL injections
$full_name = $mysqli->escape_string($_POST['name']);
$email = $mysqli->escape_string($_POST['email']);
$password = $mysqli->escape_string(password_hash($_POST['password'], PASSWORD_BCRYPT));
$usertype = $mysqli->escape_string("A");
$hash = $mysqli->escape_string( md5( rand(0,1000) ) );
// Check if user with that email already exists
$result = $mysqli->query("SELECT * FROM user WHERE Email='$email'") or die($mysqli->error());
if (isset($_POST["submit"])){
// We know user email exists if the rows returned are more than 0
if ( $result->num_rows > 0 ) {
$_SESSION['message'] = 'User with this email already exists!';
// header("location: error.php");
}
else { // Email doesn't already exist in a database, proceed...
$sql = "INSERT INTO user (Email, Password, UserType, FullName, Hash) "
. "VALUES ('$email','$password', '$usertype','$full_name', '$hash')";
// Add user to the database
if ( $mysqli->query($sql) ){
$_SESSION['logged_in'] = true; // So we know the user has logged in
$_SESSION['message'] =
"You are registered";
header("location: home.php");
}
else {
$_SESSION['message'] = 'Registration failed!';
// header("location: error.php");
}
}
}
?>
sign_in.php (not working properly):
<?php
include('db_conn.php'); //db connection
session_start();
$email = $mysqli->escape_string($_POST['email']);
$result = $mysqli->query("SELECT * FROM user WHERE Email='$email'");
if (isset($_POST["submit"])){
if ( $result->num_rows == 0 ){ // User doesn't exist
$_SESSION['message'] = "User with that email doesn't exist!";
// header("location: error.php");
}
else { // User exists
$user = $result->fetch_assoc();
echo $_POST['password'].$user['Password'];
if ( password_verify($_POST['password'], $user['Password']) ) {
$_SESSION['email'] = $user['Email'];
$_SESSION['full_name'] = $user['Name'];
$_SESSION['user_type'] = $user['UserType'];
// This is how we'll know the user is logged in
$_SESSION['logged_in'] = true;
header("location: home.php");
}
else {
$_SESSION['message'] = "You have entered wrong password, try again!";
// header("location: error.php");
}
}
}
?>
Don't escape the password hash, it is safe to input directly into the DB:
$mysqli->escape_string(password_hash($_POST['password'], PASSWORD_BCRYPT));
to:
password_hash($_POST['password'], PASSWORD_BCRYPT);

Trying to get login error messages/validation to work on login form?

I have a login system for a member/admin site. The login is working perfectly, but I want to verify the user and give error messages if it's not the correct user or password. So far, with what I have, it will not give any error messages although I'm not getting any errors either.
function error_message(){ $error = '';
$loginName = isset($_REQUEST['loginName']) ? $_REQUEST['loginName'] : "";
$password = isset($_REQUEST['password']) ? $_REQUEST['password'] : "";
{$results = connect($loginName);
$loginName === $results['email'];
$passwords = password_verify($password,$results['password']);
if(!$results) {$error = 'Username not found'; echo $error; header ('Location: home.php');} //if no records returned, set error to no username
else //if found {if ((isset($password)) !== (isset($passwords))) //check password, if matched log him in
{ $error = 'Password is wrong'; echo $error; header('Location: home.php');} //if not matched then set error message
}
}
if(isset($error)) {echo $error; }//if there is an error print it, this can be anywhere in the page
}
This is my connection and how it is logging in:
function connect($loginName) {
global $db;
$query = "SELECT email, level, password FROM members WHERE email ='$loginName'";
$result = $db->query($query);
$results = $result->fetch(PDO::FETCH_ASSOC);
return $results;
}
Login:
function login($loginName, $password) {
$results = connect($loginName);
if(!$results) {
header('Location: /tire/admin/home.php?err=1');
}
if ($loginName === $results['email'] && password_verify($password,$results['password'])) {
$_SESSION['loginName'] = $loginName;
if ($results['level'] === 'a') { // 1 == Administrator
$_SESSION['level'] = 'Administrator';
header('Location: /tire/admin/home.php');
} elseif ($results['level'] === 'm') { // 1 == Member
$_SESSION['level'] = 'Member';
header('Location: /tire/member/home.php');
exit;
}
}
header('Location: /tire/admin/home.php');
}
Wow, that's some nasty code we have here. Let's get started:
Let's first take a look in the connect function:
Gets the row where the email matches the loginName provided.
Return the array with the desired row.
That's correct.
Now let's take a look to the login function:
Retrieves the row where the email matches loginName.
If there is no row (email does not match any user), redirects to home.php of ¿ADMIN? with the variable $err = 1.
Recheck the email (what for?) and verify the password.
If password is correct, it checks permissions and redirects to the correspondent home.php.
Notice that if there is no matches for a permission, it redirects you to admin home.php.
Notice that if the password is incorrect, you do nothing.
I will improve this code:
function login($loginName, $password) {
$results = connect($loginName);
if(!$results) {
header('Location: /tire/error.php?code=1');
}
if (password_verify($password,$results['password'])) {
$_SESSION['loginName'] = $loginName;
if ($results['level'] === 'a') { // 1 == Administrator
$_SESSION['level'] = 'Administrator';
header('Location: /tire/admin/home.php');
} elseif ($results['level'] === 'm') { // 1 == Member
$_SESSION['level'] = 'Member';
header('Location: /tire/member/home.php');
exit;
}
} else {
header('Location: /tire/error.php?code=2');
}
}
And then in error.php (or whatever place you would like to show the errors, it's just an example):
switch($_GET['code']){
case 1:
$error = "Email invalid";
break;
case 2:
$error = "Password invalid";
break;
}
print $error
That being said, I will strongly recommend you to read about exceptions and implement the logic based on that. It's far more clean than the code above, but I didn't want to change your code so drastically.
See: http://php.net/manual/en/language.exceptions.php

Categories