1

PHPログインシステムを持っていますが、機能が不足しています。ログインする前にユーザーのメールアドレスにアクティベーションリンクを送信したいのですが、ユーザーはリンクをクリックしてアカウントをアクティベートする必要があります。また、持っているパスワードを忘れてしまった場合に備えて、新しいパスワードを要求させたいと思います...これら2つの問題を除いて、他のすべては正常に機能します。どうすればそれを達成できますか?ありがとう

usersデータベースのテーブルにあるもの:

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>
4

2 に答える 2

3

一般に、電子メールを検証するには、登録時にランダムな文字列を作成する必要があります。その文字列を、新しく登録したユーザーのIDまたは電子メールアドレスとともにデータベースに保存します。次に、電子メールに沿って、その文字列が添付されたリンクを送信します。元:

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

次に、ユーザーがそのリンクに移動したら、$ _ GET ['v']を使用してリンクからその値を取得し、データベースを確認します。次に、データベースでその特定の値を検索し、接続しているユーザーの行を編集/削除します。その値。

これにより、これが行われた後もユーザーを登録しておくための2つの方法があります。列の周囲の値を「登録済み」または「1」、あるいはほとんど何にでも設定できます。または、登録値が保存されていた行を削除できます...

つまり、ユーザーがログインするたびに、その新しい列の値を確認するか、そのユーザーが「not_activate_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>");
  }
?>

パスワードの変更に関しては、2つの異なる状況があります。1つは、古いパスワードを知っていて、それを変更したいということです...これは、メール、古いパスワード、新しいパスワードを入力するフォームを用意するのと同じくらい簡単です...データベースで入力したパスワードとメールが送信されるかどうかを確認します同じ行で...そしてそれが本当なら、あなたはただUPDATEクエリを実行して彼らのパスワードフィールドを新しいもので更新します...

パスワードのリセットに関しては、おそらくログインページのどこかにパスワードを忘れたと言うのが最も簡単な方法でしょう。彼らが彼らの電子メールを入力するページに彼らをリダイレクトするリンクで; 登録と同じように、そこにメールを送信します。次に、一意のキーとユーザーIDを保存します...そのリンクにアクセスすると、新しいパスワードを入力します。ユーザーIDと一時キーが保存されているテーブルがあります。次に、そのユーザー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

トークンとステータスという2つのフィールドをusersテーブルに追加するだけです。次に、このトークンを最後に追加するリンク(http://yourdomain.com/users/accountactivation/34gg456sas78ud)を作成し、電子メールで送信します。ユーザーがこのリンクを押すと、コントロールはアカウントのアクティブ化に移動し、クエリが実行されて、このトークンがデータベースに存在するかどうかが確認されます。はいの場合、そのユーザーのステータスを1に変更し、リンクが期限切れになるようにテーブルからトークンを変更/削除します。ユーザーがログインするときに、ユーザーステータスが1であるかどうかを確認します。はいの場合、ユーザーはログインできます。そうでない場合は、アカウントをアクティブ化するための電子メールを確認するメッセージが表示されます。

于 2013-01-12T04:24:21.397 に答える