What im basically trying to do is to confirm the identity of the user by using the mail address then Do certain database operation if the identity is verified.
I want to generate a confirmation code and send to the email address in the form of a URL.
But i do not want to maintain a database for the confirmation codes.How can i do this using encryption.Any Ideas?
it should look like:
<?php
$salt = "this is a secret key!!!";
if(isset($_GET["confirm"]) && isset($_GET["email"])){
$confirm = $_GET["confirm"];
$to_email = $_GET["email"];
if(sha1($salt.$to_email) == $confirm){
// this mail is confirmed, now do some db work
// update_db ... ();
}else{
die("error: mail not confirmed");
}
}elseif(isset($_GET["email"])){
$to_email = $_GET["email"];
$confirm_link = $_SERVER["PHP_SELF"]."?confirm=".urlencode(sha1($salt.$to_email))."&mail=".urlencode($to_email);
$msg = "to confirm ... click the link: \n ".$confirm_link;
mail($to_email,"pls. confirm your mail",$msg);
}else{
die("error message");
}
?>
You could Hash the email address in question with some secret salt and make that the token in the link. Then when you're verifying it, repeat that same process.
Best way of that is having a varchar field in your database named "activation".
So you can keep "confirmation code" there. When user has activated his account you will update it to "1". So if the field is "1"; User has activated his account. Otherwise there will be still confirmation code there and user's account is not activated. So there will be at least one column for activation process.
Related
I've got a website and when a user registers I want to check, if the entered email has already been used to register another account.
database: users
row: email
new email: $email_register
$result = $pdo->prepare("IF email_register = ? IN email FROM users $same = TRUE");
$result->execute(array($email_register));
$user = $result->fetch();
if($same == TRUE)
{
echo email already used;
}
else
{
#continue registration process
}
I want a way to know if the email is already in the db, and if it is, for the user to be sent back to the registration page with an error message (error code transmitted via header).
Assuming that users should not have more than one account per email, an easy approach is to make the email column a unique key (or primary key) in the users table. This prevents an email being used more than once.
Try this way
// check if email is taken already
$stmt = $pdo->prepare("SELECT email FROM users WHERE email_register = :email");
$stmt->execute([
'email_register ' => $email
]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (isset($user) && !empty($user)){
// Username already taken
echo "email already used";
}else{
//redirect to registration process
}
There is no need for IF in the SQL query. Just write simple select statement like:
Select email from users where email = 'example#example.com';
if query return and result it means the email is already in database if not then you can continue to the registration process.
if($exist)
{
return false; or you redirect to registration page whatever you want to do.
}
#continue registration process
I'm working on a small website which requires users to signup for an account, after which an email is sent to them with details to verify the account. After clicking on the link in the verification email, the account should be active and the user should be able to login.
I have provided 3 PHP snippets from registration.php(to register), login.php(to login) and verify.php (to verify the activation of the account)
!! I'm using WAMP server to create the database and according table
NOTE: This is the only error I receive on the registration page.
Warning: mail(): Failed to connect to mailserver at "localhost" port 25, verify your "SMTP" and "smtp_port" setting in php.ini or use ini_set() in C:\wamp\www\ONLINE BANKING\registration.php on line 541
Currently I have a few problems:
1. I am using the hmailserver, but I'm not exactly sure how to set it up
2. I need to monitor when the users have been added to the database (I assume this is only after the email verification link is clicked)
Please tell me what I'm doing wrong and how this can be fixed
**REGISTRATION.PHP**
<div id="wrap">
<!-- start PHP code -->
<?php
mysql_connect("localhost", "root", "") or die(mysql_error()); // Connect to database server(localhost) with root .
mysql_select_db("registrations") or die(mysql_error()); // Select registration database.
$email="";
if( isset($_POST['fullname']) // Is the name field being posted; it does not matter whether it's empty or filled.
&& // This is the same as the AND in our statement; it allows you to check multiple statements.
!empty($_POST['fullname']) // Verify if the field name is not empty
AND isset($_POST['email']) // Is the email field being posted; it does not matter if it's empty or filled.
&& // This is the same as the AND in our statement; it allows you to check multiple statements.
!empty($_POST['email']) ) // Verify if the field email is not empty
{
$fullname = mysql_real_escape_string($_POST['fullname']);
$email = mysql_real_escape_string($_POST['email']);
}
if(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/", $email)){
// Return Error - Invalid Email
$msg = 'The email you have entered is invalid, please try again.';
}else{
// Return Success - Valid Email
$msg = 'Your account has been created, <br /> please verify it by clicking the activation link that has been send to your email.';
}
$hash = md5( rand(0,1000) ); // Generate random 32 character hash and assign it to a local variable.
$PIN = rand(1000,5000); // Generate random number between 1000 and 5000 and assign it to a local variable.
$to = $email; // Send email to our user
$subject = 'Signup | Verification'; // Give the email a subject
$from="info#bfs.com";
$message = 'Thanks for signing up!
Your account has been created, you can login with the following credentials after you have activated your account by clicking the url below.
------------------------
echo $_POST["UserID"];
PIN: '.$PIN.'
------------------------
Please click this link to activate your account:
http://www.yourwebsite.com/verify.php?email='.$email.'&hash='.$hash.'
'; // Our message above including the link
$headers = 'From:noreply#yourwebsite.com' . "\r\n"; // Set from headers
mail($to, $subject, $message, $headers); // Send our email //Line 541
?>
<!-- stop PHP Code -->
</div>
**LOGIN.PHP**
<div id="wrap">
<!-- start PHP code -->
<?php
mysql_connect("localhost", "root", "") or die(mysql_error()); // Connect to database server(localhost) with UserID and PIN.
mysql_select_db("registrations") or die(mysql_error()); // Select registration database.
if(isset($_POST['name']) && !empty($_POST['name']) AND isset($_POST['PIN']) && !empty($_POST['PIN'])){
$UserID = mysql_escape_string($_POST['name']);
$PIN = mysql_escape_string(md5($_POST['PIN']));
$search = mysql_query("SELECT UserID, PIN, active FROM users WHERE UserID='".$UserID."' AND PIN='".$PIN."' AND active='1'") or die(mysql_error());
$match = mysql_num_rows($search);
if($match > 0){
$msg = 'Login Complete! Thanks';
}else{
$msg = 'Login Failed!<br /> Please make sure that you enter the correct details and that you have activated your account.';
}
}
?>
<!-- stop PHP Code -->
<?php
if(isset($msg)){ // Check if $msg is not empty
echo '<div class="statusmsg">'.$msg.'</div>'; // Display our message and add a div around it with the class statusmsg
} ?>
</div>
**VERIFY.PHP**
You must setup your server for sendig mail
set mail function in php.ini file to sendmail_path ="\"C:\xampp\sendmail\sendmail.exe\" -t" if you use something like xampp
and then
set senmail.ini
smtp_server=smtp.gmail.com //example
smtp_port=587
auth_username=YourMail#gmail.com
auth_password=YourMailPass
In your case you have wamp server and you should configure this server for sending mail as i stated example for xampp
I suggest if you already have a web hosting account, you can simply try it online using your Gmail or Yahoo a/c. Setting up Email on the desktop is hectic and time consuming.
Create Your web pages contains (Login page , registration page and main Page) with requirements:
1- apply a validation on registration form of username, email, password, re-type password, gender and birthdate data.
2- verification to login form data with username & password and create Login session.
3- a database connection establish to store users information and verify login data.
4- restriction to main page and access granted only if login success.
5- logout from main page and destroy user session.
moyasar_22#hotmail.com
I'm using this code as part of an email confirmation script. It works great, except I can't figure out a way to distinguish between when somebody has provided an invalid email address vs when they have simply refreshed the page (ie. already confirmed their account). The only think I can think of is putting a time stamp field in the users table that always gets updated, but I'm hoping there is a better way. I thought REPLACE would do the trick, but, while email is unique, it is not the primary key.
if (isset ($email, $token, $correctToken)){
$success = FALSE; //Set the $success variable so that we don't get an error when testing for it later
if ($token == $correctToken) {
$confirm = mysql_query("UPDATE users
SET conf = 'TRUE'
WHERE email = '$email'");
if (mysql_affected_rows() == 1) {
echo "Thank you! Your email address is confirmed and your account is actived.";
$success = TRUE;
}
}
if (!$success) {
echo "There was a problem with the confirmation. Try the link in your email again or contact us at Support#WiseRenters.com";
// Send email to admin to notify of error
exit;
}
}
Thanks in advance for the advice!
Billy
EDIT: The $email and $token variables are provided through $_GET or $_POST, in case that wasn't obvious.
A redirection would stop them from refreshing - but what if they click the link in their email again?
You should check if the current user is activated or not.
$sql = "SELECT id, conf FROM users WHERE email = '{$email}'";
$exec = mysql_query($sql) or die(mysql_error());
list( $id, $conf ) = mysql_fetch_row($exec);
if( $conf ) {
// Redirect them to their profile with a message saying "your account has already been activated"
header("Location: /profile?already_activated");
exit;
}
// your code
$confirm = mysql_query("UPDATE users
SET conf = 'TRUE'
WHERE id = '{$id}'");
In response to your comment:
Keep in mind this will only add an additional query for a user who has not activated yet. If they have activated then the redirect occurs and the page is still running only 1 query.
To optimize this a bit, you can select the user ID and confirmation status based on the email address. Then, if they do need to be activated, you can activate them based on user ID instead of email. Since an integer key is much faster, the combined time of the 2 queries will be about the same as the 1 query where you are updating based on a string column. I updated the code to reflect this.
Also, this page will probably not be accessed very frequently. Any optimizations from here would really be micro- and not really that helpful.
By the way I hope you are using mysql_real_escape_string on the email, and that conf is a boolean true/false not a string 'true'/'false'.
I am creating a forgotten password page and will be emailing a temporary password to the user so they can log in and reset their password.
What should I take into account when creating the password, what is the best method.
An idea I had is something like: $temporarypassword = sha1($_SERVER['REMOTE_ADDR'])
In an attempt to only allow them to login from the ip address where they requested the temp password. What is the best way to do this??
Code so far:
if(strpos($_SERVER['HTTP_REFERER'],'domain.com') && ($_POST['forgotpasstoken'] == sha1($_SESSION['token'].'forgotpassword'))){
if(isset($_POST['forgotemail']) && !empty($_POST['forgotemail'])){
$email = mysql_escape_string(trim($_POST['forgotemail']));
if(filter_var($email, FILTER_VALIDATE_EMAIL) === FALSE){
echo '<div class="error">Please enter a valid email address.</div>';
} else {
$sql = "SELECT email FROM users WHERE email = '$email' LIMIT 1";
$res = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($res) > 0) {
//If email/user exists
$temporarypassword = sha1($_SERVER['REMOTE_ADDR'])
//EMAIL PASSWORD HERE
echo '<div class="success">A temporary recovery password has been emailed to you.</div>';
//If email/user exits
} else {
echo '<div class="error">This email is not registered.</div>';
}
}
} else {
echo '<div class="error">Please enter an email address.</div>';
}
}
Use just a random string: it's more than likely that user tries to log in from e.g. iPhone, fails, requests a new password, and only opens the link when he's at his home PC. IPs are different, device is different, everything's different.
If you're emailing the password, there is no way to make it fully secure. Email is transmitted in plain text. And like alf said, the user may reset the password from a different IP address than the one they requested it from.
One option would be to create a random string, then display half of it on the password reset page (after the reset request is made) and half of the string in the email. Then require the user to enter both halves in a form before letting them choose a new password.
When a user forgets his password, there is an email sent to his email account with a link and token (unique) to resetpassword.php
When the authentication is correct then he is able to change the password. My question is how can this happen?
The quick and easy way is to email him a new password and let him change it through his CP, but is this a good user-experience?
$result = mysql_query("SELECT member_id FROM members WHERE forgotpass='$token'");
if(mysql_num_rows($result) == 1) {
WHAT GOES HERE?
}
else {
die("Query failed");
}
WHAT GOES HERE?
there should be something like
echo 'Your password was mailed to you';
mysql_query("UPDATE members SET password = '".$random_hashed_string."' WHERE forgotpass='$token'");
mail($to, $subject, $message." password:".$random_hashed_string, "From: support#support.com");
You will need to create a form to allow the user to select a new password. The form's action will update the database user record's password field. This will probably be a separate process, but your WHAT GOES HERE? will be an HTML form.