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框架
#以上是yii怎麼做登入的詳細內容。更多資訊請關注PHP中文網其他相關文章!