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

时间:2017-07-29 09:19:20

标签: 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');
  }  

1 个答案:

答案 0 :(得分:1)

您应该如何通过发送包含令牌的超链接的电子邮件来验证用户电子邮件地址的示例 - 您不需要在发送的任何链接中包含电子邮件地址。

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

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

并使用简单函数生成/测试令牌 - 如下所示:

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 - 所以此时验证从先前发布的代码开始。

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

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