Email 认证
Email 认证
在 Yii2 的高级应用模板的 frontend
应用程序中,提供了对用户在注册的时候填写的 email 地址进行验证及重发邮件的一系列示例代码。
一般情况下,当用户用 email 注册操作后,我们的应用系统会发送一条验证 email 的邮件给用户,用户进入自己的邮箱,打开邮件,点击邮件中的链接,才能完成邮箱认证,即账号激活。
生成邮箱验证 token
当用户注册的时候,我们会用 Yii2 的安全组件来生成邮箱验证的 token,并存入 user 表中,具体代码如下:
$verification_token = Yii::$app->security->generateRandomString() . '_' . time();
发送验证电子邮件
在注册后,发送验证电子邮件的模板,在 common/mail 路径下的 emailVerify-html.php 文件中,代码如下:
use yii\helpers\Html;
/* @var $this yii\web\View */
/* @var $user common\models\User */
$verifyLink = Yii::$app->urlManager->createAbsoluteUrl(['site/verify-email', 'token' => $user->verification_token]);
?>
<div class="verify-email">
<p>Hello <?= Html::encode($user->username) ?>,</p>
<p>Follow the link below to verify your email:</p>
<p><?= Html::a(Html::encode($verifyLink), $verifyLink) ?></p>
</div>
如上所述,我们可以看到,发送的邮件带上之前生成的邮箱验证 token,当用户收到邮件时,可以点击路由为 site/verify-email
的链接,这个控制器动作中,负责验证 email,接着看下一节:
验证用户 email
我们来看看 高级应用模板中 frontend
应用下的 SiteController
下的 actionVerifyEmail()
动作,代码如下:
namespace frontend\controllers;
use frontend\models\VerifyEmailForm;
use Yii;
use yii\base\InvalidArgumentException;
use yii\web\BadRequestHttpException;
use yii\web\Controller;
class SiteController extends Controller
{
/**
* Verify email address
*
* @param string $token
* @throws BadRequestHttpException
* @return yii\web\Response
*/
public function actionVerifyEmail($token)
{
try {
$model = new VerifyEmailForm($token);
} catch (InvalidArgumentException $e) {
throw new BadRequestHttpException($e->getMessage());
}
if (($user = $model->verifyEmail()) && Yii::$app->user->login($user)) {
Yii::$app->session->setFlash('success', 'Your email has been confirmed!');
return $this->goHome();
}
Yii::$app->session->setFlash('error', 'Sorry, we are unable to verify your account with provided token.');
return $this->goHome();
}
}
以下是验证邮箱的模型类中的代码,具体如下:
namespace frontend\models;
use common\models\User;
use yii\base\InvalidArgumentException;
use yii\base\Model;
class VerifyEmailForm extends Model
{
/**
* @var string
*/
public $token;
/**
* @var User
*/
private $_user;
/**
* Creates a form model with given token.
*
* @param string $token
* @param array $config name-value pairs that will be used to initialize the object properties
* @throws InvalidArgumentException if token is empty or not valid
*/
public function __construct($token, array $config = [])
{
if (empty($token) || !is_string($token)) {
throw new InvalidArgumentException('Verify email token cannot be blank.');
}
$this->_user = User::findByVerificationToken($token);
if (!$this->_user) {
throw new InvalidArgumentException('Wrong verify email token.');
}
parent::__construct($config);
}
/**
* Verify email
*
* @return User|null the saved model or null if saving fails
*/
public function verifyEmail()
{
$user = $this->_user;
$user->status = User::STATUS_ACTIVE;
return $user->save(false) ? $user : null;
}
}
验证的原理很简单,就是把用户传递来的token,去 user 表里查找下,对比即可,User 模型中的代码如下:
namespace common\models;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;
class User extends ActiveRecord implements IdentityInterface
{
/**
* Finds user by verification email token
*
* @param string $token verify email token
* @return static|null
*/
public static function findByVerificationToken($token) {
return static::findOne([
'verification_token' => $token,
'status' => self::STATUS_INACTIVE
]);
}
}
重发验证电子邮件
如果注册后,第一次发送邮件,没有收到,可以重新发送验证邮件,具体示例代码如下:
namespace frontend\controllers;
use frontend\models\ResendVerificationEmailForm;
use Yii;
use yii\web\Controller;
class SiteController extends Controller
{
/**
* Resend verification email
*
* @return mixed
*/
public function actionResendVerificationEmail()
{
$model = new ResendVerificationEmailForm();
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
if ($model->sendEmail()) {
Yii::$app->session->setFlash('success', 'Check your email for further instructions.');
return $this->goHome();
}
Yii::$app->session->setFlash('error', 'Sorry, we are unable to resend verification email for the provided email address.');
}
return $this->render('resendVerificationEmail', [
'model' => $model
]);
}
}
namespace frontend\models;
use Yii;
use common\models\User;
use yii\base\Model;
class ResendVerificationEmailForm extends Model
{
/**
* @var string
*/
public $email;
/**
* {@inheritdoc}
*/
public function rules()
{
return [
['email', 'trim'],
['email', 'required'],
['email', 'email'],
['email', 'exist',
'targetClass' => '\common\models\User',
'filter' => ['status' => User::STATUS_INACTIVE],
'message' => 'There is no user with this email address.'
],
];
}
/**
* Sends confirmation email to user
*
* @return bool whether the email was sent
*/
public function sendEmail()
{
$user = User::findOne([
'email' => $this->email,
'status' => User::STATUS_INACTIVE
]);
if ($user === null) {
return false;
}
return Yii::$app
->mailer
->compose(
['html' => 'emailVerify-html', 'text' => 'emailVerify-text'],
['user' => $user]
)
->setFrom([Yii::$app->params['supportEmail'] => Yii::$app->name . ' robot'])
->setTo($this->email)
->setSubject('Account registration at ' . Yii::$app->name)
->send();
}
}
💖喜欢本文档的,欢迎点赞、收藏、留言或转发,谢谢支持!
作者邮箱:zhuzixian520@126.com,github地址:github.com/zhuzixian520