Yii2系列教程四:实现用户注册,验证,登录

JellyBool

JellyBool

本来打算昨晚写的这篇教程,但是忙着约会去了,所以现在补上吧。

上一篇写了一点点Yii2的数据库相关知识和强大的Gii,这一篇就如上一篇的最后所说的一样:在Yii2中实现用户的注册和登录。

你可以直接到Github下载源码,以便可以跟上进度,你也可以重头开始,一步一步按照这个教程来做。本期的用户注册和登录,我会使用一个很棒的composer package :dektrium/yii2-user,下面就开始我们的故事吧。

用户的注册和登录

在现在的Web应用中,几乎每一个应用都会需要用户注册,不管是使用的第三方还是自建的注册登录系统,我们都需要通过某些表单来收集一些必要的用户数据。这些功能在Yii2之中实现起来并不难,而且有很多种方法,好像很多方法都是比较直接,简单粗暴。这可能是很多人喜欢Yii的原因,就像很多人喜欢PHP一样,就是简单粗暴!

其实在Yii2中,它本身就自带了一个登录的实现:

替代文字

但是我们重复去制造这个轮子是因为我们需要一些更加实用性的改善,比如:在注册的时候,发送验证邮箱。这几乎是每一个Web应用在注册的时候都会考虑的内容。

如果你安装的是Yii2 Advanced Application Template,那么Yii2其实就把这些功能都写好了,而且你还会有一个后台管理的模块。但是我们的教程是基于Yii2's Basic Application Template,而且我提倡大家来动手造一下这个轮子。

带上我们的作案工具,我们要来造轮子了。

安装Yii2-User

我们这里的Yii2-User安装步骤参照Yii2-User官方安装文档。我们直接使用composer来进行安装:

composer require "dektrium/yii2-user:0.9.*@dev"

稍微等待一下,安装完毕之后就可以进行对应的配置了,我们需要配置的文件是config/web.php,找到components,然后在与它同级的位置增加一个modules

'components' => [

        // other settings...

    ],

'modules' => [

        'user' => [

            'class' => 'dektrium\user\Module',

            'confirmWithin' => 21600,

            'cost' => 12,

            'admins' => ['admin']

        ],

    ],

这里还需要将components下面的user部分注释掉,不然就会一直登录不了:

 /* 'user' => [

            'identityClass' => 'app\models\User',

            'enableAutoLogin' => true,

        ],*/

还有最后一步就是执行Yii2-User的migration了,在helloYii/目录下执行:

php yii migrate/up --migrationPath=@vendor/dektrium/yii2-user/migrations

然后你会看到:

替代文字

果断yes

替代文字

Bang,到这里Yii2-User安装和配置已经完成了。

配置SwiftMailer

安装完Yii2-User之后我们先不急着去想怎么实现登录和注册(其实很是比较简单的),我们之前说过的目标是实现用户在注册时候发送验证邮件的,这里我们先来配置一下我们的邮箱服务,因为Yii2-User可以直接使用邮箱来进行注册验证和密码找回等功能。在config/web.php找到mailer这个部分:

'mailer' => [

    'class' => 'yii\swiftmailer\Mailer',

    // send all mails to a file by default. You have to set

    // 'useFileTransport' to false and configure a transport

    // for the mailer to send real emails.

    'useFileTransport' => true,

],

修改成我们下面的这个样子:

'mailer' => [

        'class' => 'yii\swiftmailer\Mailer',

        'viewPath' => '@app/mailer',

        'useFileTransport' => false,

        'transport' => [

            'class' => 'Swift_SmtpTransport',

            'host' => 'smtp.live.com',

            'username' => 'jellybool@outlook.com',

            'password' => 'your-password',

            'port' => '587',

            'encryption' => 'tls',

            ],

    ],

这里由于我经常使用的是outlook,不要觉得我是奇葩。所以我在这里使用的是outlook的SMTP配置,各位可以根据自己的需要来进行相应的修改。

开始使用Yii2-User

邮箱配置好了之后,我们就可以开始使用Yii2-User了,首先我们来修改一下我们的导航栏,因为我们想实现的就是我们常常看到的在导航栏的右侧的注册和登录按钮。在/views/layouts/main.php找到:

echo Nav::widget([

            'options' => ['class' => 'navbar-nav navbar-right'],

            'items' => [

                ['label' => 'Home', 'url' => ['/site/index']],

                [

                    'label' => 'Status',

                    'items' => [

                        ['label' => 'View', 'url' => ['/status/index']],

                        ['label' => 'Create', 'url' => ['/status/create']],

                    ],

                ],

                ['label' => 'About', 'url' => ['/site/about']],

                ['label' => 'Contact', 'url' => ['/site/contact']],

                Yii::$app->user->isGuest ?

                    ['label' => 'Login', 'url' => ['/site/login']] :

                    ['label' => 'Logout (' . Yii::$app->user->identity->username . ')',

                        'url' => ['/site/logout'],

                        'linkOptions' => ['data-method' => 'post']],

            ],

        ]);

上面的启示就是我们在上一篇文章修改过后的导航栏的代码,然后用下面的代码进行替换:

$navItems=[

    ['label' => 'Home', 'url' => ['/site/index']],

    ['label' => 'Status', 'url' => ['/status/index']],

    ['label' => 'About', 'url' => ['/site/about']],

    ['label' => 'Contact', 'url' => ['/site/contact']]

  ];

  if (Yii::$app->user->isGuest) {

    array_push($navItems,['label' => 'Sign In', 'url' => ['/user/login']],['label' => 'Sign Up', 'url' => ['/user/register']]);

  } else {

    array_push($navItems,['label' => 'Logout (' . Yii::$app->user->identity->username . ')',

        'url' => ['/site/logout'],

        'linkOptions' => ['data-method' => 'post']]

    );

  }

echo Nav::widget([

    'options' => ['class' => 'navbar-nav navbar-right'],

    'items' => $navItems,

]);


修改完成之后,我们直接访问:http://localhost:8999/user/register,你将会看到下面的类似页面:

替代文字

有没有觉得很神奇?没错Yii2-User帮我们都全部写好了!然后我们输入相应的信息点击注册,之后就会看到这个信息提示页面:

替代文字

提示新说表明验证邮箱已经发送,我们登录qq邮箱去看看,果然:

替代文字

看到这个,相信大家都会很开心,有图有真相。直接点击邮件的验证链接,然后就会看到Yii2-User给我们反馈的验证成功的信息:

替代文字

注意右上角,这个时候我们已经登录到应用了,如果点击Logout就会回到登录页面:

替代文字

到这里,注册登录整个流程就实现完了,不过还有一个我们日常开发经常遇到的情况:忘记密码。嗯,对于这个情况,Yii2-User直接就提供了这个功能!你可以直接访问:http://localhost:8999/user/forgot 就可以看到了:

替代文字

嗯,就这样,很简单吧。借助Yii2-User这个强大的composer package,我们可以轻松实现用户注册,登录和忘记密码等各个功能。当然,Yii2-User还有很多特性,我们这里只是用到了很小一部分,你可以直接到文档中查看:

https://github.com/dektrium/yii2-user/blob/master/docs/README.md

最后希望这一篇文章可以帮你解决一些问题。下一步我肯能会说一下用户权限控制和管理,因为这里实现的用户注册,所以下一篇显得是自然而然的。

源码会放在 Github:https://github.com/JellyBool/helloYii

Happy Hacking

本文由 JellyBool 创作, 转载和引用遵循 署名-非商业性使用 2.5 中国大陆 进行许可。

共有 77 条评论

Anonymous

为什么你代码里没有user这个controller却直接能用?我试了下不可以的啊

Anonymous

因为用的是modules

Anonymous

博主网站不错,而且还是https的赞一个

Anonymous

对,就像@LeeBright说的一样,用的是modules,这个在Yii2-User这个package就写好的,你可以直接看看这个package的源码

Anonymous

哈哈哈,谢谢。

Anonymous

哦,我知道了,是没把web下面的index.php路由重写了

Anonymous

好的嘛,根据官方文档写好重写规则就可以了

Anonymous

楼主在github上下载下来怎么跑不起来呀!对于php我是新手

Anonymous

clone 下来之后你会得到一个helloYii的文件夹,然后修改config/db.php文件,配置好你自己的数据库连接,再修改config/web.php,配置好你的smtp服务信息,最后直接cd helloYii/web来到web目录下,启动PHP内置服务器:php -S localhost:8999,浏览器访问localhost:8999就可以了

Anonymous

需要哪些配置环境和工具,Composer、yii2……

Anonymous

需要哪些配置环境和工具,Composer、yii2……

Anonymous

composer是一个php包依赖管理工具,跟yii2没什么特殊关系,只是composer安装yii2会比较方便,而且对于后期很多的维护会带来很大的便利。
至于环境配置:参见yii2的官方文档,只要满足yii2的基本要求就可以了,基本就是php版本5.4以上就可以了

Anonymous

好的,明白

Anonymous

那就好,有什么不明白的地方可以问我

Anonymous

composer require “dektrium/yii2-user:0.9.*@dev” 一直安装失败,提示:Your requirements could not be resolved to an installable set of package.

Problem 1

  • yiisoft/yii2 2.0.2 requires bower-asset/jquery 2.1.*@stable -> no matching package found.
Anonymous

可能是由于你的PHP没有安装curl,试试安装这个php5-curl

Anonymous

php_curl 这个 扩展是已经安装了的。
上面的那个问题我也已经从yiiframework.com 找到解决办法了,多谢。

Anonymous

OK,那就好。。

Anonymous

注册发送邮件老是报response code 异常错误。。。怎么破!

------------Expected response code 250 but got code "550", with message "550 5.3.4 Requested action not taken; To continue sending messages, please sign in to your account.
"
Anonymous

在windows上用outlook配置,可以发送邮件,也经常报超时,163和qq配置都报响应码错误。。

Anonymous

检查一下配置,qq和163我都没使用过。。。他们是不是要设置什么功能

Anonymous

Swift_TransportException Expected response code 250 but got code “553”, with message "553 Mail from must equal authorized user

上面是我的错误提示,配置信息如下:

 'mailer' => [
            'class' => 'yii\swiftmailer\Mailer',
            // send all mails to a file by default. You have to set
            // 'useFileTransport' to false and configure a transport
            // for the mailer to send real emails.
            'viewPath'=>'@app/mailer',
            'useFileTransport' => false,
            'transport'=>[
                'class'=>'Swift_SmtpTransport',
                'host'=>'smtp.163.com',
                'username'=>'15501623127@163.com',
                'password'=>'***********',
                'port'=>'25',
                'encryption'=>'tls',
            ],

             'messageConfig'=>[  
                'charset'=>'UTF-8',  
                'from'=>['15501623127@163.com'=>'admin']  
            ],
        ],

但是注册的时候发送出现错误。
如果载控制器中直接调用发送邮件,是可以成功的。下面就是测试控制器发送的代码

$mail= Yii::$app->mailer->compose();   
        $mail->setTo('452937595@qq.com');  
        $mail->setSubject("邮件测试");  
        //$mail->setTextBody('zheshisha ');   //发布纯文字文本
        $mail->setHtmlBody("<br>问我我我我我");    //发布可以带html标签的文本
        if($mail->send())  
            echo "success";  
        else  
            echo "failse";
Anonymous

首先确保你的SMTP服务开启正确,这种报错都是由于SMTP服务商的。。。

Anonymous

smtp开启正确的,下面直接写在控制器就能实现发送邮件!就是用Yii2-User自己发送邮件没有成功报错了哈。

Anonymous

你收到邮件了?

Anonymous

对的,如果用控制器中自己写的方法就收到邮件了,但是使用Yii2-Use注册就报错了。。下面就是我自己写在控制器中测试发邮件的代码是成功的,

$mail= Yii::$app->mailer->compose();
$mail->setTo('452937595@qq.com');
$mail->setSubject("邮件测试");
//$mail->setTextBody('zheshisha '); //发布纯文字文本
$mail->setHtmlBody("<br>问我我我我我"); //发布可以带html标签的文本
if($mail->send())
echo "success";
else
echo "failse";
Anonymous

那可能是你没有正确配置Yii2-User吧,不然怎么会这样。。

Anonymous

Page not found. 配置完以后打开页面还是报错误。
web下面的module也已经添加

'modules' => [
				'user' => [
					'class' => 'dektrium\user\Module',
					'confirmWithin' => 21600,
					'cost' => 12,
					'admins'=>['admin']
				],
	],
Anonymous

你的环境是什么,具体报错是什么?可以看看不?

Anonymous

同样问题,没看到user controller,对module还不是很熟,能指点一下不?谢!

Anonymous

前面留了一条,后来改了改URL加上/security能找到页面,供参考,layouts/main.php:
if (Yii::app->user->isGuest) { array_push(navItems,[‘label’ => ‘Sign In’, ‘url’ => [’/user/security/login’]],[‘label’ => ‘Sign Up’, ‘url’ => [’/user/registration/register’]]);
} else {
array_push(navItems,[label=>Logout(.Yii::navItems,['label' => 'Logout (' . Yii::app->user->identity->username . ‘)’,
‘url’ => [’/site/security/logout’],
‘linkOptions’ => [‘data-method’ => ‘post’]]
);
}

但碰到另外问题,邮件提示发出,但没收到,继续尝试中。

Anonymous

把你的配置 web.php和controller的代码都贴出来我看看?

Anonymous

什么问题?

Anonymous

楼主你好,执行这一句的时候

php yii migrate/up --migrationPath=@vendor/dektrium/yii2-user/migrations,

总是报错,说是

Specified key was too long; max key length is 1000 bytes

Anonymous

我出现和他一模一样的问题,搞了一天也不知哪错了,自己写的能发出去,用yii2-user注册就是Expected response code 250 but got code “501”, with message "501 mail from address must be same as authorization user。我看文档注册的url是/user/registration/register,用/user/register显示的是404。还有邮件没发出去但是注册的账号已经写进user表了。

Anonymous

这应该是你的SMTP服务问题

Anonymous

自己写的controller用163和qq能发,但是outlook的没成功,host是smtp-mail.outlook.com还是你用的smtp.live.com,在outlook选项中启用pop就算设置完了吗?password直接用的登陆密码吗

Anonymous

看了yii2-user源码,发现改config下的params.php,可以解决大部分问题

<?php

return [
    'adminEmail' => "13132693017@163.com",//改成自己的邮箱
];
Anonymous

我不知道为啥这么多人遇到问题,我写代码貌似是一次OK了

Anonymous

他这个是正解,不改这个邮件有问题

Anonymous

我现在又有问题了,注册完后登出再次sign in会跳转到首页,但还是guset状态没登陆

Anonymous

邮件验证了吗?

Anonymous

嗯,邮箱验证了。验证完有logout(admin),但下次sign up就不行了,登陆后还是guest的label

Anonymous

楼主你好,看了你的帖子受益匪浅,但是在自己增加功能的时候遇到了一些问题,请问我如果想给表单增加一项条目怎么办?
比如增加一个用户类型的选择.我试了好久,也看了Yii2-User作者的文档,覆写了Model和user,但就是没办法把表单的数据存入数据库.
请问应该增加哪些代码来实现这个功能?

Anonymous

这是反垃圾邮件系统约束条件,
对于501和503报错的解决办法
修改一下Mailer.php(搜索就行)的$sender的值改成和你配置邮箱一样的值就行,完美解决问题
还有就是163的port值要设置成25,qq邮箱的port值要设置成587.

Anonymous

测试良久还是感觉dektrium/yii2-user这个扩展问题很大啊,是否开启urlManager对yii2-user的登陆链接会是两套不同的$query_string 。。。[汗]

Anonymous

看看 http服务器日志吧,可能是session存放目录的权限问题

Anonymous

问题很大,说得夸张了点,但是坑还是有的

Anonymous

我也出现了,是因为param里面没有配置邮箱,mailer 和param两个配置项里面都要配置

Anonymous

终于好使了,我用的是163邮箱,按照楼主的配置和这个地址的教程http://www.yii-china.com/post/detail/10.html,设置好163的smtp服务之后可以通过controller发送邮件,但是不能使用yii-user的发送邮件,报错Expected response code 250 but got code “553”, with message "553 Mail from must equal authorized user,修改config下的params.php文件,把邮箱地址修改成和yii-user配置的邮箱一致就好使辣

Anonymous

大致学了Yii1,但是学Yii2的时候看到这儿还是有点进度慢。主要是composer得使用很费劲,最后还是用了vpn进行了下载。另外:
1、希望大神带领简单学习一下composer
2、composer下下来的在vendor中是怎么被利用的
3、简单介绍一下,接下来怎么学习,怎么才能学到更多的功能
谢谢前人指路

Anonymous

第一次付费看视频,希望能很爽。
请问你的用的shell是什么软件?

Anonymous

iTerm 2

Anonymous

我也是跟他一样的问题。nav中我复制了他的代码就好了,但是用你原来的user/login和user/logout就不行。

Anonymous

Connection to tcp://smtp.126.com:587 Timed Out
我用的126的邮箱,已经改了,还是说链接超时。请问这个有一个列表参考吗?谢谢

Anonymous

1、还有很多没讲到,经常出现的–prefer-dist就没讲到。
2、我用的云梯就没有你的快。请问你用的什么VPN?
3、你说可以提供下载的,但是怎么找就是没找着。。。

Anonymous

配置smtp时,用qq和163,搜狐的smtp试了两三个小时都不行,老是报错.然后一怒之下用微软账号注册一个outlook邮箱,照着jeelybool的配置,马上就能用了

Anonymous

Object not found!
The requested URL was not found on this server. The link on the referring page seems to be wrong or outdated. Please inform the author of that page about the error.

If you think this is a server error, please contact the webmaster.

Anonymous

基本上就是重写没开

Anonymous

奇葩的是我得打开URL美化才能正常访问

'urlManager' => [
            'enablePrettyUrl' => true,
            //'showScriptName' => false,
            //'rules' => [
            //],
        ],

YII2.0.8

Anonymous

Failed to authenticate on SMTP server with username "17710632850@163.com" using 2 possible authenticators,

设置POP3/SMTP/IMAP:
POP3/SMTP服务
IMAP/SMTP服务
收取最近30天邮件

温馨提示:请使用授权码登录第三方邮件客户端
设置POP3/SMTP/IMAP:
开启客户端删除邮件提醒

当邮件客户端删除邮件时,系统会通过邮件发送提醒信息
 
提示
服务器地址:
POP3服务器: pop.163.com
SMTP服务器: smtp.163.com
IMAP服务器: imap.163.com
网易官方邮件客户端:
网易邮箱大师
其他邮件客户端:
PC端设置帮助
移动端设置帮助(iOS、Android、Symbian)
安全支持:
POP3/SMTP/IMAP服务全部支持SSL连接

请问这个是什么原因

Anonymous

qq 邮箱的 smtp 没开启正确吧。你去看看仔细的 qq 邮箱 smtp 的设置文档

Anonymous

看了看大家的评论,修改了param.php里面的配置就好了

Anonymous

最后点击sign up和sign in 都是404…我的Yii2-User已经安装好了呀,还有哪个步骤不对的吗?

Anonymous

“后来改了改URL加上/security能找到页面”,我看上面的回复这样了做真的可以访问了~[呵呵]

Anonymous

嗯哼,问题解决就好

Anonymous

在web/params.php里面配置下’adminEmail’ => ‘z××××××@126.com’,写上自己的邮箱就好了,遇到和你一样的问题

Anonymous

这些用 SMTP 的,用国内的邮箱基本都很坑,最好就是使用 Google 的来测试。。。

Anonymous

那个还有,这个网站在有些浏览器上图片显示有些问题,提些反馈哈,作者有空找几个浏览器测试下

qinyuLT

请问,运行了您的项目,配置了db和web,但是注册的时候一闪而过,什么也没有提示是怎么回事?

小k书

点了Sign up 又弹回来,是不是要写个控制器??

admin123456

发送邮件总是报错,邮箱配置那具体应该怎么写(QQ邮箱)

admin123456

“Address in mailbox given [] does not comply with RFC 2822, 3.6.2.”,这就是报的错,怎么解决,在线等,急急急急!!!

775397252

url路由貌似不对,比如注册路由应该是user/registration/register

frozen47

跟着文章做下来, 完成到注册页面, 输入信息并点击按钮之后, 就没有反应了