5

私は以前にこれを尋ねましたが、それがどのように機能するかを理解していないようです(私はたくさん試しましたが、まったく成功しませんでした)登録時にユーザーの電子メールアドレスにアクティベーションリンクを送信し、許可しない方法を教えてください.ユーザーがメール アドレスのリンクをたどってアカウントを有効にするまで、私は何をすべきか?全然わかりません・・・助けてください。

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 
    ) 
"; 

$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> 
<a href="register.php">Register</a>
4

3 に答える 3

10

1 つは、このスクリプトでユーザーに何もメールを送信していないことです。あなたがすべきことは、登録テーブルを作成し、そこに値をトークンと日時とともに保存することです。URL ベースの識別子。電子メールとタイムスタンプの連結の単純な md5 は正常に機能します。

$token = md5($_POST['email'].time());

次に、次のようなリンクをユーザーにメールで送信します。 http://www.yoursite.com/register/confirm?token=yourmd5token

このスクリプトは、そのトークンから保存されたユーザー情報を取得し、日時が 1 時間以内であることを確認してから、確認時にのみデータをユーザー テーブルにプッシュするため、テーブルが不必要にいっぱいになることはありません。

あなたが提供したコードに基づくと、あなたは PHP の真の初心者ではありません。したがって、言及されているものの例をグーグルで検索しても問題はありません。通常、SO は簡単なヘルプと基本的な QA に使用されるため、これは複雑すぎてすべてを書き出すことはできません。あなたのものは完全なプロジェクトのものです。

于 2013-01-17T02:27:51.580 に答える
1

以下は、電子メール検証を行う 1 つの方法の概念的な概要です。この質問は、回答に実際のコードを追加するにはレベルが高すぎます。また、これは検証を行う最善の方法ではない可能性があることを考慮してください。単純な方法です。

データベースに 2 つの列を追加します。

  • is_verified
  • 検証トークン

login.php で:

  1. ユーザーの作成時に is_verified=0 を設定し、ランダムな verify_token を作成します。
  2. ユーザーを作成したら、トークンをクエリ文字列パラメーターとして使用して、verify.php へのリンクを作成します。
  3. 確認用のリンクが記載された電子メール アドレスに電子メールを送信します。
  4. ユーザーをverificationWaiting.phpというページにリダイレクトし、電子メールを確認してリンクをクリックするよう警告します。

次のような verify.php というページを作成します。

  1. クエリ文字列内のトークンについてデータベースをチェックし、トークンを持つユーザーが見つかった場合は is_verified フラグを true に設定します。
  2. ユーザーをログインページにリダイレクトします

login.php を変更して、ユーザーが認証条件として is_verified を設定していることを確認します。

これは、それを行う 1 つの方法の概要にすぎません。追加できる多くの追加機能があります。これが開始に役立つことを願っています。

于 2013-01-17T02:30:29.757 に答える
0

いくつかのオプションがあります。「アクティブ」などの名前の新しい列を追加し、ユーザーが生成されたリンク (たとえば、yoursite.com/activate.php?key=) をクリックするまでデフォルトで 0 にすることができます。

キーを持っている=ユーザーのメールアドレスのようなもの。

ユーザーがリンクをクリックし、以前の登録でファイルに保存されているパスワードを入力したら、アクティブな列を 1 に設定できます。

2 番目のオプションは、ランダムなパスワードを生成し、ユーザーにメールからパスワードを取得するよう要求することです。したがって、有効な電子メールアドレスが必要です。

于 2013-01-17T02:28:37.607 に答える