1. 程式人生 > >Yii2.0登入功能程式碼實現

Yii2.0登入功能程式碼實現

yii歸檔檔案中的basic應用是帶登入功能的,見user相關。同時basic中已經帶了基本登入Login模板。

一、建立controller/action

這裡用到SiteController的actionLogin方法:

namespace app\controllers;

use Yii;
use yii\filters\AccessControl;
use yii\web\Controller;
use yii\filters\VerbFilter;
use app\models\LoginForm;
use app\models\Userinfo;
use app\models
\ContactForm; use app\models\EntryForm; class SiteController extends Controller {

用的basic中預設siteController

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, ]); }

Action也是預設的。

二、Model和LoginForm

public function login()
{
    if ($this->validate()) {
        return Yii::$app->user->login($this->getUser(), $this
->rememberMe ? 3600*24*30 : 0); } return false; } public function getUser() { if ($this->_user === false) { $this->_user = Userinfo::validateUsername($this->username, $this->password); } return $this->_user; }

LoginForm中的預設login方法,在yii/app/web下需要返回一個user資訊記錄在session和cookie中,記錄的資訊是$this->getUser()中返回的static類,如下。

public static function validateUsername($username, $password)
{
    try {
        $records = Yii::$app->db->createCommand("select * from userinfo where username = '".$username."'")->queryAll();
    } catch (Exception $e) {
        var_dump($e);
    }

    if ($records && $records[0]["password"] == $password) {
        $currentUser = [
            'usernameL' => $records[0]["username"],
            'passwordL' => $records[0]["password"],
            'emailAddressL' => $records[0]["emailAddress"],
            'authKey' => 'test100key',
            'accessToken' => '100-token',
        ];
        return new static($currentUser);
    }

    return null;
}

static($currentUser)是建立了當前的一個類,屬性要對應上:

class Userinfo extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
    public $usernameL;
    public $passwordL;
    public $emailAddressL;
    public $authKey;
    public $accessToken;

三、yii登入基本原理

1、需要配置引數,加入user擴充套件

'components' => [
        'user' => [
            'identityClass' => 'app\models\Userinfo',
            'enableAutoLogin' => true,
        ],
        ...
]

identityClass就是用於處理user的model,可以使用Yii2高階模板自帶的user,也可以自己寫,需要實現IdentityInterface介面(這裡寫的是userInfo,利用gii的crud生成)

2、關於user

配置好user後,可以在全域性使用Yii::$app->user訪問;
user的重要屬性,isGuest:判斷使用者是否登入;id,儲存登入使用者的唯一識別標識,由我們自己設定,具體如何設定,且看後文分解;
user的重要方法,login():將使用者資訊儲存在session、cookie中;logout():將使用者資訊從session、cookie中銷燬;
Note that User only maintains the user authentication status. It does NOT handle how to authenticate a user. The logic of how to authenticate a user should be done in the class implementing yii\web\IdentityInterface.
//user元件的工作只是維護使用者的認證狀態(即簡單的操作session和cookie)。它並不負責認證使用者。認證過程的邏輯實現統統由一個實現了IdentityInterface介面的類實現;

3、IdentityInterface

這個介面定義了5個函式:
findIdentity();
getId();
findIdentityByAccessToken();
getAuthKey();
validateAuthKey;
這5個函式當中,最重要的可能就是getId()了。這個函式由你實現,由傳遞給user的物件在login的時候呼叫,用於設定user的id屬性值!所以,在實現這個函式的時候,你返回的是什麼,那麼user元件記住的user id就是什麼。其他幾個函式的具體實現,請參照文件;

4、登入

假設我們定義了一個名為User的AR模型類(注意應用元件user的區別),User對應了一張我們儲存有使用者登入資訊的資料表;如果我們要使用User來完成使用者認證,User就必須實現上文提及的IdentityInterface;
1、伺服器接受到使用者提交的使用者名稱和密碼;
2、生成User例項$model;
3、賦值:$model->load(Yii::$app->request->post());
4、檢查使用者輸入以及驗證使用者名稱和密碼:$model->validate();
5、登入Yii::$app->user->login($model,$duration);

5、自動登入

要實現自動登入,需要設定引數$enableAutoLogin
$duration必須大於零;
使用$isGuest判斷使用者是否已經登入;

四、遇到的問題

class Userinfo extends \yii\db\ActiveRecord implements \yii\web\IdentityInterface
{
    public $usernameL;
    public $passwordL;
    public $emailAddressL;
    public $authKey;
    public $accessToken;

model中有資料庫屬性,這裡是記錄登入屬性,二者名稱需要不一樣,否則會影響使用者新增。