yii做登錄的方法示例:
1、LoginForm.php
用戶登陸模塊,所提交的是username和password,所以我們要先建立一個Model,專門處理用戶提交的數據,所以先新建一個LoginForm.php,以下為代碼:
<?php namespace appmodulesbackendmodels; use Yii; use yiibaseModel; /** * 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">//① ????{ ????????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 appmodulesbackendmodels; use yiidbActiveRecord; 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的代碼如下:
<?php namespace appmodulesbackendmodels; use yiidbActiveRecord; class User extends ActiveRecord implements yiiwebIdentityInterface { public static function tableName(){ return 'user'; } public static function findIdentity($id){ return static::findOne($id); } public static function findIdentityByAccessToken($token,$type=null){ return static::findOne(['accessToken'=>$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); } ? ???<span> </span>?/** ????<span> </span>?*?Generates?"remember?me"?authentication?key ????<span> </span>?*/ ????????public?function?generateAuthKey()????????????????????//③ ????????{ ???????<span> </span>$this->auth_key?=?Yii::$app->security->generateRandomString(); ???????<span> </span>$this->save(); ????????} ? } ?>
①findByUsername():在LoginForm的代碼中,引用了這個方法,目的是根據用戶提交的username返回一個在數據表與username相同的數據項,即AR實例。
②validatePassword():這里對用戶提交的密碼以及當前AR類的密碼進行比較。
③generateAuthKey():生成隨機的auth_key,用于cookie登陸。
一共寫了兩個Model類:LoginForm和User,一個用于接收用戶提交的數據,一個用于獲取數據庫的數據。
控制器(Controller)
控制器,主要是用于數據的提交,把用戶提交的數據填充到相應的模型(Model)中,然后根據模型返回的信息進一步渲染視圖(View),或者執行其他邏輯。
這里,把控制器命名為LoginController.php,以下是完整的實現代碼:
<?php namespace appcontrollers; use Yii; use yiifiltersAccessControl; use yiiwebController; use yiifiltersVerbFilter; use appmodelsLoginForm; use appmodelsContactForm; 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 yiiwebView */ /* @var $form yiibootstrapActiveForm */ /* @var $model appmodelsLoginForm */ use yiihelpersHtml; use yiibootstrapActiveForm; $this->title?=?'Login'; $this->params['breadcrumbs'][]?=?$this->title; ?> <div> ????<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>{input}</div>n<div>{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>{input}?{label}</div>n<div>{error}</div>", ????????])??> ????????<div> ????????????<div> ????????????????=?Html::submitButton('Login',?['class'?=>?'btn?btn-primary',?'name'?=>?'login-button'])??> ????????????</div> ????????</div> ????<?php ActiveForm::end(); ?> ????<div> ????????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>appmodelsUser::$users</code>. ????</div> </div>
推薦學習:yii框架