5

我之前已经问过这个问题,但我似乎从未了解它是如何工作的(我尝试了很多但根本没有成功)有人可以告诉我如何在注册时向用户电子邮件地址发送激活链接并且不允许用户,直到他们通过点击电子邮件地址中的链接激活他们的帐户?我该怎么办?完全看不懂。。。求大神帮忙。。。

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

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

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

一方面,您没有通过电子邮件向用户发送此脚本中的任何内容。您应该做的是创建一个注册表并将值与令牌和日期时间一起存储在那里。一些基于 URL 的标识符。电子邮件和时间戳 concat 的简单 md5 可以正常工作。

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

然后通过电子邮件向用户发送链接 - 例如: http ://www.yoursite.com/register/confirm?token=yourmd5token

该脚本将从该令牌中获取存储的用户信息,确保日期时间在一个小时左右,然后仅在确认后将数据推送到用户表中,这样您就不会不必要地填充表。

根据您提供的代码,您并不是真正的 PHP 初学者。所以你应该没有问题谷歌搜索提到的事情的例子。因为通常 SO 用于快速帮助和基本 QA,所以这太复杂了,无法为您全部写出来。你的更像是一个完整的项目。

于 2013-01-17T02:27:51.580 回答
1

这是进行电子邮件验证的一种方法的概念性概述。这个问题仍然太高,无法在答案中添加任何实际代码。另外,请考虑这可能不是进行验证的最佳方式,只是一种简单的方式。

向数据库添加 2 列:

  • is_verified
  • 验证令牌

在 login.php 中:

  1. 创建用户时设置is_verified=0,并随机创建一个verification_token。
  2. 创建用户后,使用令牌作为查询字符串参数构建到 verify.php 的链接。
  3. 向包含链接的电子邮件地址发送电子邮件以进行验证
  4. 将用户重定向到名为verificationWaiting.php 的页面,该页面会提醒他们检查电子邮件并单击链接。

创建一个名为 verify.php 的页面:

  1. 检查数据库中查询字符串中的令牌,如果找到具有令牌的用户,则将 is_verified 标志设置为 true。
  2. 将用户重定向到登录页面

修改 login.php 以确保用户已将 is_verified 设置为身份验证条件。

这只是对一种方法的广泛概述。您可以添加许多其他功能。希望这有助于您入门。

于 2013-01-17T02:30:29.757 回答
0

您有一些选择,您可以添加一个名为“活动”的新列,并将其默认为 0,直到用户单击生成的链接(例如,yoursite.com/activate.php?key=)

拥有密钥 = 类似于用户的电子邮件地址。

用户单击链接并输入他们之前注册时存档的密码后,您可以将活动列设置为 1。

第二个选项是生成一个随机密码,并要求用户从他/她的电子邮件中获取密码。因此需要一个有效的电子邮件地址。

于 2013-01-17T02:28:37.607 回答