yii做登录的方法示例:
1、LoginForm.php
用户登陆模块,所提交的是username和password,所以我们要先建立一个Model,专门处理用户提交的数据,所以先新建一个LoginForm.php,以下为代码:
<?php namespace app\modules\backend\models; use Yii; use yii\base\Model; /** * LoginForm is the model behind the login form. */ class LoginForm extends Model { public $username; public $password; public $rememberMe = true; private $_user = false; /** * @return array the validation rules. */ public function rules()<span style="white-space:pre"> </span>//① { return [ // username and password are both required [['username', 'password'], 'required','message'=>""], // rememberMe must be a boolean value ['rememberMe', 'boolean'], // password is validated by validatePassword() ['password', 'validatePassword'], ]; } /** * Validates the password. * This method serves as the inline validation for password. * * @param string $attribute the attribute currently being validated * @param array $params the additional name-value pairs given in the rule */ public function validatePassword($attribute, $params) { if (!$this->hasErrors()) { $user = $this->getUser(); if (!$user || !$user->validatePassword($this->password)) { $this->addError($attribute, 'Incorrect username or password.'); } } } /** * Logs in a user using the provided username and password. * @return boolean whether the user is logged in successfully */ public function login() { if ($this->validate()) { if($this->rememberMe) { $this->_user->generateAuthKey();//③ } return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0); } return false; } /** * Finds user by [[username]] * * @return User|null */ public function getUser() { if ($this->_user === false) { $this->_user = User::findByUsername($this->username); //② } return $this->_user; } }
该Model是根据basic模板自带的LoginForm修改而成,代码中大多有注释,这里关注以下代码:
①号代码处是rules规则,rules规则定义了填充过来的数据的规则,验证所填的数据是否为空,是否符合格式之类的,其中有一栏是password,对应的规则是validatePassword,会自动调用当前类的validatePassword()方法,注意与下文的User类对应的方法区分。
②号代码,调用了User类里面的findByUsername方法,这个User类下面会写到,主要是为了返回一个AR类实例,与当前LoginForm的数据进行比较。
③号代码,这里暂时不提,等讲到cookie登陆的时候再提。
2、User.php
(1)ActiveRecord 类
在完成LoginForm后,我们还缺少一些东西,从用户接受到数据了,那么还需要从数据库取出相应的数据来进行比较,所以我们接下来需要完成的是一个从数据库获取的数据的类——AR类,全称是ActiveRecord,活动记录类,方便用于查找数据,只要类名和数据表的表名相同,那么它就能从这个数据表中获取数据,比如说这样:
<?php namespace app\modules\backend\models; use yii\db\ActiveRecord; class User extends ActiveRecord{ } ?>
还能自己添加返回的表名,只要在这个类中重写以下方法:
public static function tableName(){ return 'user'; }
(2)IdentityInterface 接口
一般来说,从数据库查找数据,只需要继承AR类即可,但是,我们这个是用户登录模型,核心是验证,所以自然需要实现核心的验证功能,就像LoginForm模型提到的validatePassword一样,实际的验证逻辑是在当前的User模型完成的。一般来说,实现IdentityInterface接口,需要实现以下方法:
public static function findIdentity($id); //① public static function findIdentityByAccessToken($token, $type = null); //② public function getId(); //③ public function getAuthKey(); //④ public function validateAuthKey($authKey); //⑤
①findIdentity:是根据id查找数据表对应的数据
②findIdentityByAccessToken是根据AccessToken(上文提到的)查找对应的数据,而AccessToken我们在数据表也有这个字段,那么它到底有什么用呢?其实AccessToken在我们当前的用户登陆模型中用处并不大,它是专门用于Resetful登陆验证用到的,具体可自行百度,这里不展开说明。
③getId:返回当前AR类所对应的id
④getAuthKey:返回当前AR类所对应的auth_key
⑤validateAuthKey:这个方法比较重要,是我们后面要讲到的cookie登陆验证的核心所在。
在我们的User.php实现接口,然后重写以上方法,完整的User.php的代码如下:
$token]); } public static function findByUsername($username){ //① return static::findOne(['username'=>$username]); } public function getId(){ return $this->id; } public function getAuthkey(){ return $this->auth_key; } public function validateAuthKey($authKey){ return $this->auth_key === $authKey; } public function validatePassword($password){ //② return $this->password === md5($password); } /** * Generates "remember me" authentication key */ public function generateAuthKey() //③ { $this->auth_key = \Yii::$app->security->generateRandomString(); $this->save(); } } ?>
①findByUsername():在LoginForm的代码中,引用了这个方法,目的是根据用户提交的username返回一个在数据表与username相同的数据项,即AR实例。
②validatePassword():这里对用户提交的密码以及当前AR类的密码进行比较。
③generateAuthKey():生成随机的auth_key,用于cookie登陆。
一共写了两个Model类:LoginForm和User,一个用于接收用户提交的数据,一个用于获取数据库的数据。
控制器(Controller)
控制器,主要是用于数据的提交,把用户提交的数据填充到相应的模型(Model)中,然后根据模型返回的信息进一步渲染视图(View),或者执行其他逻辑。
这里,把控制器命名为LoginController.php,以下是完整的实现代码:
<?php namespace app\controllers; use Yii; use yii\filters\AccessControl; use yii\web\Controller; use yii\filters\VerbFilter; use app\models\LoginForm; use app\models\ContactForm; class SiteController extends Controller { public function actionIndex() { return $this->render('index'); } public function actionLogin() { if (!\Yii::$app->user->isGuest) { //① return $this->goHome(); } $model = new LoginForm(); //② if ($model->load(Yii::$app->request->post()) && $model->login()) { //③ return $this->goBack(); //④ } return $this->render('login', [ //⑤ 'model' => $model, ]); } public function actionLogout() { Yii::$app->user->logout(); return $this->goHome(); } }
①首先从\Yii::$app->user->isGuest中判断,当前是否是游客模式,即未登陆状态,如果用户已经登陆,会在user类中储存当前登陆用户的信息。
②如果当前是游客,会先实例化一个LoginForm模型
③这行代码是整个login方法的核心所在,首先:$model->load(Yii::$app->request->post())把post过来的数据填充进$model,即LoginForm模型,如果返回true,则填充成功。接着:$model->login():执行LoginForm类里面的login()方法,可以从login()方法里面看到,将会执行一系列的验证。
视图(View)
在实现了model和controller,接下来是视图部分,由于用户需要输入数据,所以我们要提供一个表单,在Yii2中,提供了ActiveForm快速生成表单,代码如下:
<?php /* @var $this yii\web\View */ /* @var $form yii\bootstrap\ActiveForm */ /* @var $model app\models\LoginForm */ use yii\helpers\Html; use yii\bootstrap\ActiveForm; $this->title = 'Login'; $this->params['breadcrumbs'][] = $this->title; ?> <div class="site-login"> <h1><?= Html::encode($this->title) ?></h1> <p>Please fill out the following fields to login:</p> <?php $form = ActiveForm::begin([ 'id' => 'login-form', 'options' => ['class' => 'form-horizontal'], 'fieldConfig' => [ 'template' => "{label}\n<div class=\"col-lg-3\">{input}</div>\n<div class=\"col-lg-8\">{error}</div>", 'labelOptions' => ['class' => 'col-lg-1 control-label'], ], ]); ?> <?= $form->field($model, 'username')->textInput(['autofocus' => true]) ?> <?= $form->field($model, 'password')->passwordInput() ?> <?= $form->field($model, 'rememberMe')->checkbox([ 'template' => "<div class=\"col-lg-offset-1 col-lg-3\">{input} {label}</div>\n<div class=\"col-lg-8\">{error}</div>", ]) ?> <div class="form-group"> <div class="col-lg-offset-1 col-lg-11"> <?= Html::submitButton('Login', ['class' => 'btn btn-primary', 'name' => 'login-button']) ?> </div> </div> <?php ActiveForm::end(); ?> <div class="col-lg-offset-1" style="color:#999;"> You may login with <strong>admin/admin</strong> or <strong>demo/demo</strong>.<br> To modify the username/password, please check out the code <code>app\models\User::$users</code>. </div> </div>
推荐学习:yii框架
Atas ialah kandungan terperinci yii怎样做登录. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!