I am new to PHP, and I have been working on setting up a reset password script. The biggest problem I am having is storing the last part of the URL into the variable $token.
What exactly do I need to have to ensure that the $token variable gets set after the user clicks the 'Reset Password' button? As of now, after the button is clicked, $token is not set to anything and the url turns into "www.website.com/resetpassword.php" without the token at the end. Thanks for your help!
Here is my form code:
<form method="post" action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>">
<div class="login_form">
<h2 style="font-family: Helvetica, sans-serif; font-size: 28pt; padding-top: 50px;">Forgot Password</h2>
<input type="email" name="email" placeholder="Your Email" maxlength="60"/>
<?php
if ( isset($sucMSG) ) {
echo '<span class="successful_registration">'.$sucMSG.'</span>';
}
if ( isset($matchError) ) {
echo '<span class="text-danger">'.$matchError.'</span>';
}
if ( isset($keyError) ) {
echo '<span class="text-danger">'.$keyError.'</span>';
}
?>
<br>
<input type="password" name="pass" placeholder="New Password" maxlength="255" />
<br>
<input type="password" name="cpass" placeholder="Confirm Password" maxlength="255" />
<input type="hidden" name="token" value= "random" />
<br>
<button type="submit" name="btn-reset">Reset Password</button>
<br><br><br>
<br><br><br><br><br><br>
</div>
</form>
Here is the PHP code:
if (isset($_POST['btn-reset'])){
// Gather the post data
$email = trim($_POST['email']);
$email = strip_tags($email);
$pass = trim($_POST['pass']);
$pass = strip_tags($pass);
$cpass = trim($_POST['cpass']);
$cpass = strip_tags($cpass);
$token = $_GET ['token'];
// Retrieve token from database
$stmt = $conn->prepare('SELECT token FROM token WHERE userEmail=? and NOW() < expire_date');
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$resetKey = $row['token'];
}
// Does the new reset key match the old one?
if ($resetKey == $token && isset($token)){
if ($pass == $cpass){
//hash and secure the password
$password = password_hash($pass, PASSWORD_DEFAULT);
// Update the user's password
$stmt = $conn->prepare('UPDATE user SET userPass = ? WHERE userEmail = ?');
$stmt->bind_param('s', $password);
$stmt->bind_param('s', $email);
$stmt->execute();
$conn = null;
$sucMSG = "Your password has been successfully reset.";
unset($email);
unset($pass);
unset($cpass);
unset($token);
unset($resetKey);
}
else
$matchError = "Your password's do not match.";
}
else
$keyError = "Your password reset key is invalid.";
}
Here is the PHP code from the previous step (forgotpassword.php):
if (isset($_POST['email'])){
$email = trim($_POST['email']);
$email = strip_tags($email);
$email = htmlspecialchars($email);
$stmt = $conn->prepare('SELECT * FROM user WHERE userEmail = ?');
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result();
$count=mysqli_num_rows($result);
// If the count is equal to one, we will send message other wise display an error message.
if($count==1){
$rows=mysqli_fetch_array($result);
$length = 55;
$token = bin2hex(random_bytes($length));//Creating Token
$create_date = date('Y-m-d H:i:s',strtotime("now"));
$expire_date = date('Y-m-d H:i:s',strtotime("+3 hours"));
//Using prepared statements to prevent SQL Injection
$stmt = $conn->prepare('INSERT INTO token (token, userEmail, create_date, expire_date) VALUES (?, ?, ?, ?)');
$stmt->bind_param('ssss', $token, $email, $create_date, $expire_date);
$stmt->execute();
// Create a url which we will direct them to reset their password
$pwrurl = 'https://www.domain.com/resetpassword.php?token='.$token;
$to = $rows['userEmail'];
//Details for sending E-mail
$from = "Company";
$body = "Company password recovery<br>
-----------------------------------------------<br><br>
Welcome to Company password recovery.
You can reset your password by clicking the following link: $pwrurl.<br><br>
Sincerely,<br><br>
Company";
$from = "support#company.com";
$subject = "Company Password recovered";
$headers1 = "From: $from\n";
$headers1 .= "Content-type: text/html;charset=iso-8859-1\r\n";
$headers1 .= "X-Priority: 1\r\n";
$headers1 .= "X-MSMail-Priority: High\r\n";
$headers1 .= "X-Mailer: Just My Server\r\n";
$sentmail = mail ( $to, $subject, $body, $headers1 );
}
elseif ($_POST['email'] == ""){
$fMSG = "Please enter an email address.";
} /*else {
if ($_POST['email'] != "")
$wMSG = "Cannot send password to your email address. Problem with sending mail.";
}*/
//If the message is sent successfully, display sucess message otherwise display an error message.
if($sentmail==1){
$sMSG = "Your Password Has Been Sent To Your Email Address.";
}
else{
if($_POST['email']!="")
$nMSG = "Cannot send password to your email address. Problem with sending mail.";
}
}
Note: I am posting as a community wiki, since no rep gain should come of this.
"Why don't you use the token as a hidden field rather than in query string, just a suggestion. – HSharma"
...
#Fred-ii- I don't know how to ping people, but the comment above this one has what ended up solving my problem. Thanks for your help! – jh95"
"#HSharma suggestion was what ultimately solved my problem. I added this to my html form <?php echo' <input type="hidden" name="token" value="'; if (isset($_GET['token'])) { echo $_GET['token']; } echo '" />' ?> and in my PHP script I added $token = $_POST ['token']; and now the token sets properly. Thanks everyone for your help!"
However and as I stated in comments:
"Since the length for it most probably surpasses the column's length, you need to increase it by ALTERing the column to be of a higher value in length, one big enough. You then need to clear the values from it and start over; you have no choice."
Related
Hi I have been scanning the answers on this subject but they seem to be individual at most, so here goes. My code is from a free repository and it works when I remove the addition I have maid.
I added "uname" because I wanted the users to be greeted by their name and not their username. It may be stupied but I like it this way. But I am missing something. My code is here:
<?php
// First we execute our common code to connection to the database and start the session
require("common.php");
// At the top of the page we check to see whether the user is logged in or not
if(empty($_SESSION['username']))
{
// If they are not, we redirect them to the login page.
header("Location: login.php");
// Remember that this die statement is absolutely critical. Without it,
// people can view your members-only content without logging in.
die("Redirecting to login.php");
}
// This if statement checks to determine whether the edit form has been submitted
// If it has, then the account updating code is run, otherwise the form is displayed
if(!empty($_POST))
{
// Make sure the user entered a valid E-Mail address
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
{
die("Invalid E-Mail Address");
}
// If the user is changing their E-Mail address, we need to make sure that
// the new value does not conflict with a value that is already in the system.
// If the user is not changing their E-Mail address this check is not needed.
if($_POST['email'] != $_SESSION['username']['email'])
{
// Define our SQL query
$query = "
SELECT
*
FROM admin_users
WHERE
email = :email
";
// Define our query parameter values
$query_params = array(
':email' => $_POST['email'],
':uname' => $_POST['uname']
);
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Retrieve results (if any)
$row = $stmt->fetch();
if($row)
{
die("This E-Mail address is already in use");
}
}
// If the user entered a new password, we need to hash it and generate a fresh salt
// for good measure.
if(!empty($_POST['password']))
{
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
$password = hash('sha256', $_POST['password'] . $salt);
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
}
else
{
// If the user did not enter a new password we will not update their old one.
$password = null;
$salt = null;
}
// Initial query parameter values
$query_params = array(
':email' => $_POST['email'],
':uname' => $_POST['uname'],
':user_id' => $_SESSION['username']['id'],
);
// If the user is changing their password, then we need parameter values
// for the new password hash and salt too.
if($password !== null)
{
$query_params[':password'] = $password;
$query_params[':salt'] = $salt;
}
// Note how this is only first half of the necessary update query. We will dynamically
// construct the rest of it depending on whether or not the user is changing
// their password.
$query = "
UPDATE admin_users
SET
uname = :uname
email = :email
username = :username
";
// If the user is changing their password, then we extend the SQL query
// to include the password and salt columns and parameter tokens too.
if($password !== null)
{
$query .= "
, password = :password
, salt = :salt
";
}
// Finally we finish the update query by specifying that we only wish
// to update the one record with for the current user.
$query .= "
WHERE
id = :user_id
";
try
{
// Execute the query
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
// Now that the user's E-Mail address has changed, the data stored in the $_SESSION
// array is stale; we need to update it so that it is accurate.
$_SESSION['username']['email'] = $_POST['email'];
// This redirects the user back to the members-only page after they register
header("Location: private.php");
// Calling die or exit after performing a redirect using the header function
// is critical. The rest of your PHP script will continue to execute and
// will be sent to the user if you do not die or exit.
die("Redirecting to private.php");
}
?>
<?php include("header.php"); ?>
<?php include("menu.php"); ?>
<div id="header_wrapper">
<h1>Edit Account</h1>
<form action="edit_account.php" method="post">
Username:<br />
<b><?php echo htmlentities($_SESSION['username']['username'], ENT_QUOTES, 'UTF-8'); ?></b>
<br /><br />
Navn:<br />
<input type="text" name="uname" value="<?php echo htmlentities($_SESSION['username']['uname'], ENT_QUOTES, 'UTF-8'); ?>" />
<br /><br />
Brugernavn:<br />
<input type="text" name="username" value="<?php echo htmlentities($_SESSION['username']['username'], ENT_QUOTES, 'UTF-8'); ?>" />
<br /><br />
E-Mail Address:<br />
<input type="text" name="email" value="<?php echo htmlentities($_SESSION['username']['email'], ENT_QUOTES, 'UTF-8'); ?>" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" /><br />
<i>(leave blank if you do not want to change your password)</i>
<br /><br />
<input type="submit" value="Update Account" />
</form>
</div>
<?php include("footer.php"); ?>
The error
Error: "Failed to run query: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens"
First of all I'm very new to PHP so don't be to hard on me. I'm trying to make a forgot password system for my website, but I can't update the password in the mysql database with sha1. If I do it before sha1 encrypting it works(commented out query in the code)
What I want is to receive a random password on the users mail, but in the database I want it to be encrypted with sha1.
Could really use some help here.
<?php
include("connect.php");
if(isset($_POST["email"])) {
$email = $con->real_escape_string($_POST["email"]);
$data = $con->query("SELECT * FROM bruker WHERE ePost='$email'");
if ($data->num_rows > 0) {
$str = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
$str = str_shuffle($str);
$str = substr($str, 0, 15);
$passwordD = $str;
//$con->query("UPDATE bruker SET passord = '$passwordD' WHERE ePost='$email'");
echo $passwordD;
$url = "http://localhost/example";
$msg = "Your new password is: $passwordD\nTo change your password, please visit this: $url";
$subject = "Reset Password";
$headers = "From: Vikerfjell" . "\r\n";
mail($email, $subject, $msg, $headers);
$salt = 'IT2_2017';
$passwordE = sha1($salt.$passwordD);
echo $passwordE;
$con->query("UPDATE bruker SET passord = '$passwordE' WHERE ePost='$email''");
} else {
echo "Please check your link:";
}
} else {
header("Location: index.php");
}
mysqli_close($con);
?>
<form name="form" action="" method="post">
<input type="text" name="email" value="">
<input type="submit" name="update password" />
</form
check the form method in the first then remove the single qoute in this line of code to be as shwon
$con->query("UPDATE bruker SET passord = '$passwordE' WHERE ePost='$email' ");
Note: the mail function will not work on the localhost
Am creating an application... everything is fine so far. In my registration system have used prepared statement and password hashing and have also try to validate user input in my form fields as well. In order for this system to be completed i need to create a forgot password system which means user can request for new password.
What have done is i have a testing site with all the files, which means i can test if works before adding it to the production site.
With the forgot password have used mysqli once everything is working fine i will then update to prepared, because am still learning prepared statement and doing it this way help me understand so don't judge.
The problem am having with my forgot password is the password is not updating once change. see this screenshot: http://prntscr.com/d5hage
Also as mentioned above have used http://prntscr.com/d5hbg1 in my register and verify in my log-in. But how do used the hashing in my forgot password or how do i update it. In my code below have used md5 which am aware is broken. Please all my coding below.
Reset_Password.php
<?php
// include connection
require_once('include/connection.php');
if(isset($_POST['submit'])){
$user_id = base64_decode($_GET['encrypt']);
$passnew = password_hash($password, $_POST['new_password'], PASSWORD_BCRYPT, array( 'cost' => 12 ) );
$sql = "UPDATE `olami560_test`.`user` SET `password` =? WHERE `user`.`id` =?";
$stmt = $con->prepare($sql);
$stmt->bind_param('si',$passnew, $user_id);
$stmt->execute();
if ($stmt->errno) {
echo "FAILURE!!! " . $stmt->error;
}
else echo "Password Changed Successfully.Click on link to login <a href='http://www.olaskee.co.uk/project/allocation/progress/index.php'>Login</a>{$stmt->affected_rows} rows";
$stmt->close();
}
?>
<form method="post" action="<?php echo $_SERVER['HTTP_REFERER']; ?>" >
<label>New Password</label>
<input type="password" name="new_password"/>
<input type="submit" name="submit" value="Reset" />
</form>
forgot_password.php
<?php
// include connection
require_once('include/connection.php');
if(isset($_GET) && !empty($_GET['email'])){
$email = mysqli_real_escape_string($con,$_GET['email']);
$query = "SELECT id
FROM `user`
WHERE `user_name` LIKE '".$email."'
OR `email` LIKE '".$email."'";
$result = mysqli_query($con,$query);
$Results = mysqli_fetch_array($result);
if(count($Results)>=1)
{
$query2 = "SELECT email
FROM `user`
WHERE `user_name` LIKE '".$email."'
OR `email` LIKE '".$email."'";
$result2 = mysqli_query($con,$query2);
$emailvalue = mysqli_fetch_array($result2);
//$token = md5(uniqid(rand(),true));
//$encrypt = md5($Results['id']);
$encrypt = base64_encode($Results['id']);
$message = "Your password reset link send to your e-mail address.";
$to = $emailvalue['email'];
$subject="Forget Password";
$from = 'leksmaster#gmail.com';
$body= 'Hi, <br/> User <br/>You Requested for Reset Password. <br><br>http://www.olaskee.co.uk/project/allocation/tms/reset_password.php?token='.$token.'&encrypt='.$encrypt.'&action=reset<br/> <br/>--<br>.olaskee<br>';
$headers = "From: " . strip_tags($from) . "\r\n";
$headers .= "Reply-To: ". strip_tags($from) . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";
mail($to,$subject,$body,$headers);
echo $message;
}
else
{
$message = "Account not found please signup now!!";
echo $message;
}
}
?>
I hope have provide enough explanation for you to understand. Thanks any input.
ok, looking through the code there are a few things I think you need to look at.
On the form change this
<form method="post" action="<?php echo $_SERVER['HTTP_REFERER']; ?>" >
to
<form method="post" action="" >
This should submit the form to itself.
The hashing really needs to be password_hash() use the following and it will get you started
$passnew = password_hash( $password, $_POST['new_password'], PASSWORD_BCRYPT, array( 'cost' => 12 ) );
On the form for resetting the password it is a good idea to have the user input the new password twice, that way you can check if they have repeated the password correctly.
if( $_POST[ 'pass1' ] == $_POST[ 'pass2' ] ) // Process else error
In your forgot_password.php file you are calling the same sql statement twice. Call it once, check if the row count is greater then one, if it is use the data from within the result, no need to call it again to do the same thing.
Hopefully this will get you going, have a good day.
I am new to PHP and MYSQL and am working on a registration/login form project to build up my knowledge but I am a bit stuck, so hope you can help.
I have a database on PHPMyAdmin and my registration form searches to see if the email address already exists if not to insert all the information into the database. This works fine. I also have a login form which searched for the email address and password to see if they matched any in the database, if so to log in. This worked fine.
My issue came when I started to learn about password salts/hashing. I can still register okay but when I try to login with details already in the database it doesn't seem to match the passwords up to allow me to log in.
register.php
<?php
error_reporting(E_ALL);
require 'db_connect.php';
// Stores the information submitted from the form via the $_POST variable
// if the request method in the form is POST then execute the following code (read the submitted information - send the email and redirect to the header location
// if it is NOT POST then it will skip this code block and show blank contact form
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$fname = trim($_POST["fname"]);
$lname = trim($_POST["lname"]);
$cname = trim($_POST["cname"]);
$email = trim($_POST["email"]);
$pass1 = trim($_POST["pass1"]);
$pass2 = trim($_POST["pass2"]);
// VALIDATIONS
// All required fields must be entered
if ($fname == "" OR $lname == "" OR $email == "" OR $pass1 == "" OR $pass2 == "") {
$error_message = "You must fill in all the required fields.";
}
// password must contain 6 characters min
if (strlen($pass1) < 6) {
$error_message = "Password must be at least 6 characters long";
}
//passwords must match each other
if ($pass1 != $pass2) {
$error_message = "Passwords do not match";
}
// hash and salt password - PASSWORD_DEFAULT uses the php default hashing algorithm -
// cost is the expense used to generate the hash (higher the number the more secure but slower the page load)
$password_save = password_hash($pass1 . SALT , PASSWORD_DEFAULT, array('cost' => 10 ));
// if there's not a previous error message run a database query to look if the email address entered matches any already in the database.
if (!isset ($error_message)){
$query = "SELECT * FROM registration_tbl WHERE email = '".$email."'";
$query_run = mysqli_query($dbc, $query);
// if the query locates more than 0 (i.e 1+) records with matching email addresses then echo out the error
// else insert all new form data in to the database and echo a success message
if (mysqli_num_rows($query_run)>0) {
$error_message = "Email Address ".$email." is already registered";
} else {
$sql = "INSERT INTO registration_tbl (first_name,last_name,company_name,email,password,reg_datetime) VALUES ('".$fname."','".$lname."','".$cname."','".$email."','".$password_save."', NOW())";
$query_run = mysqli_query($dbc, $sql);
echo "Registration Successful";
}
}
login.php
<?php
error_reporting(E_ALL);
require 'db_connect.php';
if ($_SERVER["REQUEST_METHOD"] == "POST") {
$email = trim($_POST["email"]);
$pass = trim($_POST["pass"]);
// VALIDATIONS
// both fields must be entered to log in
if($email == "" OR $pass == "") {
$error_message = "Both fields must be completed ";
}
$hashandsalt = password_hash($pass . SALT, PASSWORD_DEFAULT, array('cost' => 10 ));
// if no error message is set - send a query to the database for all records in the registration_tbl where the email matches one in the database
// if the query returns less than 1 record (i.e no matches in the database) show error message
// else if found in the database save the login details to session variables and then
// redirect to the logged-in.php page
if (!isset ($error_message)) {
$query = "SELECT * FROM registration_tbl WHERE email ='".$email."'";
$query_run = mysqli_query($dbc, $query);
if (mysqli_num_rows($query_run)<1 ){
$error_message = "Your login details do not match, please double check and try again1";
} else {
while($row = mysqli_fetch_array($query_run)) {
echo ($row['password']) ."<br>";
echo $pass ."<br>";
echo $hashandsalt;
if (password_verify($pass, $hashandsalt)){
$_SESSION['firstname'] = $row['first_name'];
$_SESSION['lastname'] = $row['last_name'];
$_SESSION['email'] = $row['email'];
$_SESSION['password'] = $row['password'];
$_SESSION['id'] = $row['ID'];
header("location: logged-in.php");
} else {
$error_message = "Your login details do not match, please double check and try again";
}
}
}
}
}
?>
<div class="wrapper">
<?php
if(!isset ($error_message)) {
echo '<p>Please complete the log in details </p>';
} else {
echo $error_message;
}
?>
<form method="post" action="login.php">
<table>
<tr>
<th>
<label for="email"> Email Address </label>
</th>
<td>
<input type="email" name="email" id="email" value="<?php if(isset($email)) { echo htmlspecialchars($email); } ?>">
</td>
</tr>
<tr>
<th>
<label for="pass"> Password </label>
</th>
<td>
<input type="password" name="pass" id="pass">
</td>
</tr>
</table>
<input type="submit" value="Log in">
</form>
The results of the 3 echos I have in the login.php
echo ($row['password']) ."<br>";
This one will show the hashed password from the database
echo $pass ."<br>";
This one will show whatever password is entered
echo $hashandsalt;
This one shows a new hashed password which differs each time the page is refreshed
This is where my query is I am obviously missing something which is not allowing the password entered to match up to the already stored hashed password.
I have scoured the internet including number of stack overflow posts but I can't quite seem to figure out what I have done wrong. This is my first post so I hope I am posting enough information for you.
Any ideas guys?
p.s I know I need to add the mysqli_real_escape_string - this was my next job after figuring this one out :ve
To verify the password you need to check with the stored password-hash from the database. There is no need to call password_hash() in login.php.
login.php
if (password_verify($pass, $row['password']))
Also there is no need to add a salt before hashing, the function password_hash() will add it automatically.
register.php
$password_save = password_hash($pass1, PASSWORD_DEFAULT, array('cost' => 10 ));
I have already asked this before but I never seem getting how it works(I tried a lot but no success at all) could someone tell me how can I send a activation link to the users email address up on registration and don't allow the user until they activate their account by following the link in the email address? What should I do? I'm not getting it at all...please help me out..
What I have in a table users in database:
1 id int(11) AUTO_INCREMENT
2 username varchar(255)
3 password char(64)
4 salt char(16)
5 email varchar(255)
register.php
// First we execute our common code to connection to the database and start the session
require("common.php");
// This if statement checks to determine whether the registration form has been submitted
// If it has, then the registration code is run, otherwise the form is displayed
if(!empty($_POST))
{
// Ensure that the user has entered a non-empty username
if(empty($_POST['username']))
{
echo "Please enter a username.";
}
// Ensure that the user has entered a non-empty password
if(empty($_POST['password']))
{
die("Please enter a password.");
}
// Make sure the user entered a valid E-Mail address
// filter_var is a useful PHP function for validating form input, see:
if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL))
{
die("Invalid E-Mail Address");
}
$query = "
SELECT
1
FROM users
WHERE
username = :username
";
$query_params = array(
':username' => $_POST['username']
);
try
{
// These two statements run the query against your database table.
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
// Note: On a production website, you should not output $ex->getMessage().
// It may provide an attacker with helpful information about your code.
die("Failed to run query: " . $ex->getMessage());
}
$row = $stmt->fetch();
if($row)
{
die("This username is already in use");
}
// Now we perform the same type of check for the email address, in order
// to ensure that it is unique.
$query = "
SELECT
1
FROM users
WHERE
email = :email
";
$query_params = array(
':email' => $_POST['email']
);
try
{
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
$row = $stmt->fetch();
if($row)
{
die("This email address is already registered");
}
// An INSERT query is used to add new rows to a database table.
// Again, we are using special tokens (technically called parameters) to
// protect against SQL injection attacks.
$query = "
INSERT INTO users (
username,
password,
salt,
email
) VALUES (
:username,
:password,
:salt,
:email
)
";
$to = "email";
$subject = "Your Account Information!";
$body = <<<EMAIL
Hello {'email'}, here is your account information!
Username:{'username'}
Password:{'password'}
Please activate your account by clicking the following activation link:
http://www.mywebsite.com/activate.php?aid={$aid}
EMAIL;
$headers = 'From: noreply#yourdomain.com' . "\r\n" .
'Reply-To: noreply#yourdomain.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
if(mail($to, $subject, $body, $headers)){
echo("<p>Your account information was successfully sent to your email - ('email')! <br><br>Please open your email and click the activation link to activate your account.</p><br><p>If you do not see your account information in your inbox within 60 seconds please check your spam/junk folder.</p>");
} else {
echo("<p> Unfortunately, your account information was <u>unsuccessfully</u> sent to your email - ('email'). </p>");
}
$salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647));
$password = hash('sha256', $_POST['password'] . $salt);
for($round = 0; $round < 65536; $round++)
{
$password = hash('sha256', $password . $salt);
}
$query_params = array(
':username' => $_POST['username'],
':password' => $password,
':salt' => $salt,
':email' => $_POST['email']
);
try
{
// Execute the query to create the user
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
}
header("Location: login.php");
die("Redirecting to login.php");
}
?>
<h1>Register</h1>
<form action="" method="post">
Username:<br />
<input type="text" name="username" required value="" />
<br /><br />
E-Mail:<br />
<input type="text" name="email" required value="" />
<br /><br />
Password:<br />
<input type="password" required name="password" value="" />
<br /><br />
<input type="submit" value="Register" />
</form>
login.php
<?php
// First we execute our common code to connection to the database and start the session
require("common.php");
$submitted_username = '';
if(!empty($_POST))
{
$query = "
SELECT
id,
username,
password,
salt,
email
FROM users
WHERE
username = :username
";
// The parameter values
$query_params = array(
':username' => $_POST['username']
);
try
{
// Execute the query against the database
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex)
{
die("Failed to run query: " . $ex->getMessage());
}
$login_ok = false;
$row = $stmt->fetch();
if($row)
{
$check_password = hash('sha256', $_POST['password'] . $row['salt']);
for($round = 0; $round < 65536; $round++)
{
$check_password = hash('sha256', $check_password . $row['salt']);
}
if($check_password === $row['password'])
{
$login_ok = true;
}
}
if($login_ok)
{
unset($row['salt']);
unset($row['password']);
$_SESSION['user'] = $row;
// Redirect the user to the private members-only page.
header("Location: private.php");
die("Redirecting to: private.php");
}
else
{
// Tell the user they failed
print("The Username/Password is invalid.");
$submitted_username = htmlentities($_POST['username'], ENT_QUOTES, 'UTF-8');
}
}
?>
<h1>Login</h1>
<form action="login.php" method="post">
Username:<br />
<input type="text" name="username" required value="<?php echo $submitted_username; ?>" />
<br /><br />
Password:<br />
<input type="password" name="password" value="" required />
<br /><br />
<input type="submit" value="Login" />
</form>
Register
For one you're not emailing the user anything in this script. What you should do is create a registration table and store the values there along with a token and a datetime. Some URL based identifier. A simple md5 of the email and timestamp concat would work fine.
$token = md5($_POST['email'].time());
Then email the user a link - something like:
http://www.yoursite.com/register/confirm?token=yourmd5token
This script would fetch the stored user info from that token, make sure the datetime was within an hour or so, then push the data into the user table only on confirmation so you don't fill up a table unnecessarily.
Based on the code you provided, you're not a true beginner in PHP. So you should have no problems google searching examples of the things mentioned. This is too involved to write it all out for you since typically SO is used for quick help and basic QA. Yours is more of a full project thing.
Here is a conceptual overview of one way to do email verification. This question is still too high level to add in any real code to the answer. Also, please consider this may not be the best way to do verification, just a simple way.
Add 2 columns to the database:
is_verified
verification_token
In login.php:
When creating the user set is_verified=0 and create a random verification_token.
After creating the user, build a link to verify.php with the token as a query string parameter.
Send an email to the email address with the link to verify
Redirect the user to a page called verificationWaiting.php which alerts them to check their email and click the link.
Create a page called verify.php that:
Checks the database for a the token in the query string and sets the is_verified flag to true if the user with the toke is found.
Redirects the user to the login page
Modify login.php to make sure the user has is_verified set as an authentication condition.
This is just a broad overview of one way to do it. There are many additional features you could add. Hope this helps get you started.
You have some options, you can add a new column named something like "active" and default that to 0 until the user has clicked on a generated link (say, yoursite.com/activate.php?key=)
have the key = something like the users email address.
Once the user has clicked the link and entered the password they have on file from previously registering, you can set the active column to 1.
The second option is to generate a random password, and require the user to get the password from his/her email. Thus requiring a valid email address.