1

我有一个 php 登录系统,但它缺乏功能。我想在用户登录之前将激活链接发送到用户的电子邮件地址,他们必须单击链接才能激活帐户。我还想让他们需要新密码,以防他们忘记了他们拥有的密码……除了这两个问题外,其他一切都很好。我是如何做到的?谢谢

users在数据库表中的内容:

1   id          int(11)       AUTO_INCREMENT    
2   username    varchar(255)        
3   password    char(64)    
4   salt        char(16)    
5   email       varchar(255)

注册.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>

登录.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>
4

2 回答 2

3

通常,要验证电子邮件,您需要在注册时创建一个随机字符串;并将该字符串与新注册用户的 ID 或电子邮件地址一起存储在您的数据库中。然后在您的电子邮件中向他们发送附有该字符串的链接。前任:

<a href="http://www.mywebsite.com/activate.php?v=329857320952">Activate your account now</a>

然后,当他们转到该链接时,您使用 $_GET['v'] 从链接中获取该值并检查您的数据库...然后您在数据库中搜索该特定值并编辑/删除与之连接的用户的行那个值。

然后,这将为您带来两种在此发生后保持用户注册的方法。您可以将列周长值设置为“已注册”或“1”或几乎任何东西;或者您可以删除具有该存储注册值的行...

这意味着每次用户登录时,您都需要检查该新列值或该用户是否存在于“not_activated_yet”表中。有很多方法可以做到这一点,但这是一个非常基本的过程。

以下是一些可以帮助您的基本脚本...在用户满足您将其放入数据库的 php 附近的所有注册要求后,您可以使用它向他们发送电子邮件...

<?php
$to = "$user_email";
 $subject = "Your Account Information!";
  $body = <<<EMAIL
Hello {$user_firstname} {$user_lastname}, here is your account information!

Username:{$user_username}
Password:{$user_pass}

Please activate your account by clicking the following activation link:
http://www.mywebsite.com/activate.php?aid={$aid}

EMAIL;

$headers = 'From: notify@yourwebsite.com' . "\r\n" .
    'Reply-To: notify@yourwebsite.com' . "\r\n" .
    'X-Mailer: PHP/' . phpversion();

if (mail($to, $subject, $body, $headers)) {
   echo("<p>Your account information was successfully sent to your email - ($user_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 - ($user_email).</p>");
  }
?>

至于更改密码有两种不同的情况。一个是他们知道他们的旧密码并且只想更改它......这就像他们输入他们的电子邮件,旧密码和新密码一样简单......您检查您的数据库中输入的密码和电子邮件是否进入使用同一行...如果是这样,您只需运行 UPDATE 查询以使用新的密码字段更新他们的密码字段...

至于密码重置,最简单的方法可能是在登录页面的某个地方说忘记密码?使用链接将他们重定向到他们输入电子邮件的页面;就像注册一样,您向他们发送一封电子邮件。然后你存储唯一的密钥和用户ID......一旦在那个链接上,他们输入一个新密码;您可以在其中找到存储用户 id 和 temp-key 的表;然后更新该用户 ID 的表密码。

编辑:另外,如果您想要代替所有设置临时密钥的东西,您可以将电子邮件发送到密码,但假设您的数据库中的密码已加密,您将不得不使用临时密钥。

忘记密码相关代码(第 1 部分-发送):

<?php
if(isset($_POST['submit'])){
$email = $_POST['email'];
//generate a random string
/// insert the key and email into a row in some table of your choosing.
///send email to the email address with the code above.
///echo success so the user knows everything worked.
}
?>
<form action='' method='POST>
<input type='text' name='pass'>
<input type='submit' name='submit' value='Send Password Request'>
</form>

第 2 部分处理:

<?php
$key = $_GET['key']; //gets key from the link you sent in your e-mail; what temporarily connects to that user.
// search your database table for that key
// once you have that users id delete the row in the password-request table and insert the password into your users table row.
?>
于 2013-01-12T04:20:06.750 回答
0

Simply add 2 fields say token and status to the users table. Now create a link adding this token at the end like (http://yourdomain.com/users/accountactivation/34gg456sas78ud) and send it in email. When user hits this link, the control goes to the account activation where a query is run to verify if this token exists in the database. If yes, change that user's status to 1 and also change/remove the token from the table so that the link expires. When user logs in , check if user status is 1. If yes, user can login else a message is displayed to check email to activate account.

于 2013-01-12T04:24:21.397 回答