I have got a php login system but it lacks to features. I would like to send activation link to a users email address before they log in, they have to click on a link to activate the account. I also would like to let them require new password in case they forget the one they have…everything else works fine except these two issues.how I do achieve that? thanks
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
)
";
$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>
<a href="register.php">Register</a>
In general to validate an email what you need to do is upon registration create a random string; and store that string in your database with either the newly registered user’s id or email address. Then along in your e-mail you send them a link that has that string attached. EX:
Then when they go to that link you use $_GET[‘v’] to get that value from the link and check your database… you then search your database for that specific value and edit/delete the row of the user connected with that value.
Which then brings you to two ways to keep a user registered after this takes place. You can either set a column perimeter value to ‘registered’ or ‘1’ or pretty much anything; or you can delete the row that had that stored registration value…
Which means every-time a user logs in you need to check on either that new column value or if that user exists in the ‘not_activated_yet’ table. There are many ways to do this but this is a pretty basic procedure to follow.
Here are some basic scripts that can help you…
After a user meets all of your registration requirements near the php in which you put them in your database you can use this to email them…
As for changing passwords there are two different circumstances. One is that they know their old password and just want to change it… This is as simple as having a form where they enter their email, oldpassword, and newpassword… You check if in your database the entered password and email go with the same row… and if that is true you just run an UPDATE query to update their password field with a new one…
As for the password resetting the easiest method would probably be to have somewhere on the login page say forgot your password? With a link that redirects them to a page where they enter their email; and just like registration you send them an email with there. Then you store the unique key and user id… Once on that link they enter a new password; at which you find the table which the users id and temp-key were stored; then update the table password for that user id.
EDIT: Also if you want instead of all the setting temporary key stuff you could just send the e-mail to the password but assuming your passwords in your database are encrypted you would have to use a temp-key.
Forgot-Password Related Code (Part 1-sending):
Part 2 Processing: