Why are you trying to re-invent the wheel.
Php already has builting password encryption functions so why using Sha256 + Salt.
Again they are two type of authentication
1.) Session Based Login
2.) Token Based Login.
From your write-up you are combining session login with token login. You will need to decide which one that you want to apply.
Consequently they are alot of php validation or sanitization functions that you need to know to keep your code more secured.
1.) use strip_tags()
This will strips out all html elements from form inputs or variables
Eg
$email = strip_tags($_POST['email']);
2.) use htmlentities or htmlspecialchars to prevent XSS Attack.
This converts htmls tags to their respective entities. its only used when printing or echoing result to html page to
You will see how i used it in the welcome.php page
See Applications:
$email = htmlentities($_POST['email']);
3.) escaping variables against sql injection Attack
If you are using Mysqli, the best sql method to be used is prepared Statement.
Alternatively you can still escape variables using mysqli_real_escape_string() functions
See Application
// escape variables Against sql injections
$email = mysqli_real_escape_string($conn, $_POST['email']);
4.) If you are using session based login, You need to use sessionId regenerate method. This will help to regenerate new session
Id as user login thus preventing session fixation attack. do not worry you will need how to use it in the login.php code below
See Application:
// first you will need to initialize sessions
session_start();
session_regenerate_id();
This are just few among other security measures
Lets have a look at Session based login using php password verify functions
Assume this is your
registeration.php
<?php
$conn = mysqli_connect("localhost","root","","demo");
if(!$conn){
die("Connection error: " . mysqli_connect_error());
}
if(isset($_POST['submit'])){
$firstName = mysqli_real_escape_string($conn,$_POST['first_name']);
$surName = mysqli_real_escape_string($conn,$_POST['surname']);
$email = mysqli_real_escape_string($conn,$_POST['email']);
$password = mysqli_real_escape_string($conn,$_POST['password']);
$options = array("cost"=>4);
$hashPassword = password_hash($password,PASSWORD_BCRYPT,$options);
$sql = "insert into users (first_name, last_name,email, password) value('".$firstName."', '".$surName."', '".$email."','".$hashPassword."')";
$result = mysqli_query($conn, $sql);
if($result)
{
echo "Registration successfully";
}
}
?>
This is now how your login.php code will look like
<?php
$conn = mysqli_connect("localhost","root","","demo");
if(!$conn){
die("Connection error: " . mysqli_connect_error());
}
if(isset($_POST['submit'])){
$email = mysqli_real_escape_string($conn,$_POST['email']);
$password = mysqli_real_escape_string($conn,$_POST['password']);
$sql = "select * from users where email = '".$email."'";
$rs = mysqli_query($conn,$sql);
$numRows = mysqli_num_rows($rs);
if($numRows == 1){
$row = mysqli_fetch_assoc($rs);
if(password_verify($password,$row['password'])){
echo "Password verified and ok";
// initialize session if things where ok.
session_start();
session_regenerate_id();
$_SESSION['surname'] = $row['surname'];
$_SESSION['first_name'] = $row['first_name'];
$_SESSION['email'] = $row['email'];
// take me to welcome.php page
header('Location: welcome.php');
}
else{
echo "Wrong Password details";
}
}
else{
echo "User does not exist";
}
}
?>
Welcome.php will now look like code below to show authenticated users session info.
//use htmlentities or htmlspecialchars to prevent XSS Attack.
<?php echo htmlentities($_SESSION['surname'], ENT_QUOTES, "UTF-8"); ?>
<?php echo htmlspecialchars($_SESSION['first_name'], ENT_QUOTES, "UTF-8"); ?>
<?php echo htmlentities($_SESSION['email'], ENT_QUOTES, "UTF-8"); ?>
Now in your post I Saw where you wrote sending a generated token with every http request. In this case I guess you are
trying to mitigate CSRF Attack.
Here is the best and most secured way to do once you logged in
To prevent CSRF you'll want to validate a one-time token, POST'ed and associated with the current session.
Something like the following . . .
On the page where the user requests eg to insert a record for payments:
payment.php
<?php
session_start();
$token= md5(uniqid());
$_SESSION['payment_token']= $token;
session_write_close();
?>
<html>
<body>
<form method="post" action="payment_save.php">
<input type="hidden" name="token" value="<?php echo $token; ?>" />
Amount: <input type="hidden" name="token" value="100 usd" />
<input type="submit" value="submit" />
</form>
</body>
</html>
Then when it comes to actually inserting the record:
payment_save.php
<?php
session_start();
$token = $_SESSION['payment_token'];
unset($_SESSION['payment_token']);
session_write_close();
if ($token && $_POST['token']==$token) {
// Insert the record for payment
} else {
// log message. You are vulnerable to CSRF attack.
}
?>
The token should be hard to guess, unique for each insert request, accepted via $_POST only and expire after a few minutes
(expiration not shown in this illustrations).