Yii2框架源碼分析之如何實現註冊和登陸

註冊

advanced模板中,進入frontend/index.php?r=site%2Fsignup頁面,能夠看到框架的註冊頁面
圖片描述php

填寫完UsernameEmailPassword後點擊Signup後,若是格式不對,frontend/models/SignuForm中的rules()函數會進行初步驗證,全部格式正確後,數據傳輸到 frontend/controllers /SiteController中的 actionSignup()函數中,函數加載用戶輸入的註冊信息,在frontend/models/SignupForm中的signup()函數,web

如下引用的文字爲解釋函數中的具體細節,不閱讀不影響總體,由於沒有摺疊文字功能,故採用引用的方法,下同
if (!$this->validate()) {
   return null;
}

signup() 函數首先調用 yii2/base/Model中的validate() 函數進行驗證
第一步,清除使用frontend/models/SignuForm中的rules()函數在用戶輸入時的錯誤信息數據庫

if ($clearErrors) {
    $this->clearErrors();
}

第二步,beforeValidate()函數觸發beforeValidate事件並返回true
第三步,設置scenario,默認是default
第四步,由於這裏的$attributeNamesnullwindows

$attributeNames = $this->activeAttributes();

執行後返回yii2

array(3) { [0]=> string(8) "username" [1]=> string(5) "email" [2]=> string(8) >"password" }

第五步,$this->getActiveValidators()會獲得frontend/models/SignuForm中的rules()中11條驗證規則給validateAttributes()進行驗證
第六步,執行afterValidate()函數觸發afterValidate事件
最後 若是全部驗證都經過,$this->hasErrors()false,因此函數最後返回truecookie

咱們看一下數據表user的字段
圖片描述session

用戶輸入了usernamepasswordemailYii2框架是如何生成其餘的字段的呢,先看password_hash,在SignupFrom中的signup函數中的密碼生成是setPassword函數,該函數在common/models/User中,setPassword函數調用了yii2/base/Security中的每一條規則generatePasswordHash函數。app

if (function_exists('password_hash')) {
    /** @noinspection PhpUndefinedConstantInspection */
    return password_hash($password, PASSWORD_DEFAULT, ['cost' => $cost]);
}

若是有,就使用password_hash函數進行加密,若是PHP沒有password_hash函數,就使用crypt函數加密,初步判斷應該是爲了兼容PHP低於5.5的版本,畢竟大於5.5的版本纔開始有password_hash函數框架

common/models/Usersignup()函數在對password加密後,就會繼續生成一個auth keyauth key是當用戶在登陸的時候點擊 remember me的時候的驗證信息,frontend

auth key生成的方法也是在yii2/base/Security中的generateRandomString,generateRandomString調用generateRandomKey函數,若是你的PHP版本爲是5.2~5.6或者是7,那就是用random_bytes生成一個32個字節的字符串,若是不是,當你用的系統時windows而且安裝了OpenSSL,就會調用openssl_random_pseudo_bytes函數生成,若是你未安裝OpenSSL,就會使用mcrypt_create_iv生成。
若是你使用的系統不是windows,就須要調用/dev/urandom,FreeBSD系統特殊,會調用/dev/random,而後調用stream_set_read_buffer方法生成8字節的字符文件,生成後,經過fread函數讀取該文件中的32個字節,而後返回該數據。

password_reset_token在用戶註冊的時候是爲空的,當用戶忘記密碼在登陸頁面點擊reset it 後生成的,用來給用法發送郵件後重置密碼時進行驗證。
statuscommon/models/User中定義的

const STATUS_DELETED = 0;
const STATUS_ACTIVE = 10;

用戶註冊時rules中的status默認爲爲10,
created_timeupdated_time也是在common/models/User中的behaviors()函數中生成

用戶的數據驗證合格,加上框架生成的數據,而後存儲進數據的user表裏。

登陸

關於frontend/controllers/SiteController中的actionSignup()中的

if (Yii::$app->getUser()->login($user)) {
    return $this->goHome();
}

就是用戶註冊後,這時該用戶的數據已經寫入數據庫了,開始登陸的過程了
登陸的過程在yii2/web/User裏的login()函數中
第一步,執行beforeLogin()函數觸發beforeLogin事件
第二步,switchIdentity()函數把我的信息換成當前用戶的信息,把全部的cookie都銷燬,而後把當前用戶的信息都存入到sessioncookie
第三步,獲取當前用戶的id和用戶登陸的ip,並寫入到log
第四步,執行afterLogin()函數觸發afterLogin事件
最後 返回true

判斷登陸成功後,return $this->goHome();跳轉到主頁。

若有錯誤,不吝賜教。

相關文章
相關標籤/搜索