PHP 和 MySQL 电子邮件验证不起作用

标签 php html mysql

我有一个问题。我在我的网站上通过电子邮件验证进行了注册。两天前还可以用,但昨天就停止了。我尝试更改代码,但什么也没发生。问题是代码没有找到任何匹配项。这是代码:

    ob_start();
 require_once 'include/connect.php';
 $pripojenie=mysql_query("SELECT * FROM users");
 $row=mysql_fetch_array($pripojenie);
 if(isset($_GET['tokenCode'])){
    $token = $_GET['tokenCode'];
    $query = "UPDATE users SET userStatus='Y' WHERE tokenCode='$token'";
    if($dbcon->query($query)){
            //odoslať email
        $to=$_GET['userEmail'];
        $subject='Účet aktivovaný';
        $headers = "MIME-Version: 1.0" . "\r\n";
        $headers .= "Content-type:text/html;charset=UTF-8" . "\r\n";
        $headers .= 'From: <noreply@limix.eu>' . "\r\n";
        $text="<!DOCTYPE html>
        <html>
        <head>
        </head>
        <body>
        <p>Ahoj!<br><br>Ďakujem za aktiváciu účtu na webovej stránke <a href='http://limix.eu'>LiMix.eu</a>.<br><br>S pozdravom<br>Maximilián Csank
        </body>
        </html>";
        mail($to, $subject, $text, $headers);
        header('Location: index.php?error=4');
        exit();

 }
 //ak je už aktívny, presmerovať na chybu
 } else if ($row['userStatus']=='Y') {
    header('Location: index.php?error=7');
    exit();
} else {
//ak je zlý token, presmerovať na chybu
header('Location: index.php?error=5');
exit();
 }

这段代码有什么问题?谢谢。

编辑 我有另一个代码,这是我的,但它不起作用,所以我评论了它。

$mail=$row['userEmail'];
  $toke=$row['tokenCode'];
  $token=isset($_GET['$toke']);
  $email=isset($_GET['$mail']);
  $query="UPDATE users SET active='1' WHERE tokenCode='$token', 
  userEmail='$email'";
  if ($dbcon>query($query)){
    header('Location: index.php?error=4');
  }  

最佳答案

示例说明如何通过发送带有包含 token 的超链接的电子邮件来验证用户电子邮件地址 - 您无需在发送的任何链接中包含电子邮件地址。

假设您生成的电子邮件包含如下超链接:

<a href='https://www.example.com/verify.php?token=$token'>Click here to verify registration</a>

并使用简单的函数来生成/测试 token - 像这样:

function createtoken( $email, $key ){
    return hash_hmac( 'ripemd160', sha1( $email ), $key );
}
function verifyemail( $email, $token, $key ){
    return createtoken( $email, $key )===$token;
}


/* define a secret used to hash the email address prior to sending email */
define( 'SECRET_KEY', sha1('This is ever so secret and never changes') );

然后处理用户激活

/* verify.php */
if( $_SERVER['REQUEST_METHOD']=='GET' && !empty( $_GET['token'] ) ){
    try{
        /* Get the token from the URI */
        $token=filter_input( INPUT_GET, 'token', FILTER_SANITIZE_STRING );


        $dbhost =   'localhost';
        $dbuser =   'xxx'; 
        $dbpwd  =   'xxx'; 
        $dbname =   'xxx';
        $db =   new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );


        /* assume $db is a mysqli connection */
        $sql='select distinct `email` from `users` where `token`=? and `userstatus`=?';
        $stmt=$db->prepare( $sql );

        if( $stmt ){

            $status=0;
            $stmt->bind_param( 'si', $token, $status );
            $result=$stmt->execute();

            if( $result ){

                /* Store the result & bind column to variable BEFORE getting `num_rows` */
                $stmt->store_result();
                $stmt->bind_result( $email );

                /* Fetch number of rows from db as integer ~ there should be only 1 at most */
                $rows=$stmt->num_rows;

                /* Fetch the result into the variable & tidy up */
                $stmt->fetch();
                $stmt->free_result();                   
                $stmt->close();


                if( $rows==1 ){

                    /* Token was found - validate and update db */
                    if( verifyemail( $email, $token, SECRET_KEY ) ){

                        $sql='update `users` set `userstatus`=? where `token`=?';

                        $stmt=$db->prepare( $sql );
                        if( $stmt ){
                            /*
                                in my test table `users`, the column `userstatus` is set as `tinyint(1)`
                                so 1=yes/true and 0=no/false rather than string yes/no
                            */
                            $yes=1;
                            $stmt->bind_param( 'ss', $yes, $token );
                            $result = $stmt->execute();

                            if( $result ){
                                $rows = $db->affected_rows;
                                if( $rows===1 ){
                                    $status=@mail( $email, 'success', 'email validated' );

                                    exit( header( 'Location: /login?validated='.$status ) );
                                }
                            } else {
                                throw new Exception('unable to update record',5);
                            }
                        }
                    } else {
                        throw new Exception('unable to verify email',4);
                    }
                } else {
                    /* Token cannot be found */
                    throw new Exception('Invalid token',3);
                }
            } else {
                throw new Exception('query failed',2);
            }
        } else {
            throw new Exception('unable to prepare sql statement',1);
        }
    }catch( Exception $e ){
        exit( header( 'Location: /index.php?error='.$e->getCode().'&message='.$e->getMessage() ) );
    }
}

--

它是 $token 的值,需要记录在数据库中(与用户的电子邮件地址相同的记录)并在 HTML 电子邮件中发送的超链接中使用。

define( 'SECRET_KEY', sha1('This is ever so secret and never changes') );

$token = createtoken( 'fred.bloggs@yahoo.com', SECRET_KEY ); /* yields: c6bc1ba4a8193cd965f1175197b5170c4c385040 */

基本示例users表:

mysql>describe users;
+------------+---------------------+------+-----+------------------+----------------+
| Field      | Type                | Null | Key | Default          | Extra          |
+------------+---------------------+------+-----+------------------+----------------+
| id         | int(10) unsigned    | NO   | PRI | NULL             | auto_increment |
| username   | varchar(64)         | NO   | MUL | NULL             |                |
| email      | varchar(64)         | NO   | MUL | mail@example.com |                |
| token      | varchar(64)         | NO   | MUL | default_token    |                |
| userstatus | tinyint(1) unsigned | NO   |     | 0                |                |
+------------+---------------------+------+-----+------------------+----------------+

/* add the user */
mysql>insert into `users` (`username`,`email`,`token`) values ('fred.bloggs','fred.bloggs@yahoo.com','c6bc1ba4a8193cd965f1175197b5170c4c385040');

/*

    It would be at this point ( adding user to db ) that you generate the email to the user with a confirmation link that they must click. 
    The status is set to zero / no so they should not be able to login until that is updated.

    The above is the equivalent of the user clicking "submit" after completing the form for example

*/

mysql> select * from users;
+----+-------------+-----------------------+------------------------------------------+------------+
| id | username    | email                 | token                                    | userstatus |
+----+-------------+-----------------------+------------------------------------------+------------+
|  1 | fred.bloggs | fred.bloggs@yahoo.com | c6bc1ba4a8193cd965f1175197b5170c4c385040 |          0 |
+----+-------------+-----------------------+------------------------------------------+------------+

用户单击他/她的电子邮件中的链接,然后转到 verify.php 页面(例如)和查询字符串 https://www.example.com/verify .php?token=c6bc1ba4a8193cd965f1175197b5170c4c385040 包含 token - 因此此时验证从之前发布的代码开始。

在验证方面,您往往不会看到如此简化的网址 - 但本质上这就是正在发生的情况。提供给用户点击的实际 URL 可能会复杂得多,因为有些人可能认为上述机制很容易被破坏(如果他们首先看到电子邮件)

我希望这对您的注册确认工作有所帮助〜因为您没有共享生成 token 、记录到数据库或将电子邮件发送给用户的代码部分,所以它只能作为指导而不是提供实际答案,但其中的某些部分(即准备好的语句方法)应该采用/适应您的代码,以防止顽皮的人入侵您的数据库;-)

关于PHP 和 MySQL 电子邮件验证不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45387581/

相关文章:

php - 加入后的 Doctrine ORM 序列化

php - 优化 Trie 实现

html - 如何在 SVG 中的 "zooming"时保持 viewBox 居中?

java - 复制到剪贴板脚本,包含中断和更多文本

php - 解码 JSON $_POST

php - 如何找到表中的最大值,如果有相同的值,则从找到的数据中最小的ID中检索数据(mysql 5.5.36)

javascript - 无法访问文件上传的路径键

mysql 无法更改 session 变量 group_concat_max_len

mysql - 多表删除

php - 如何在php中显示pdf