Yii2 Resultful Api 認證
使用access token 作為用户登錄認證信息
1. 修改認證
-
main.php
/*** 認證類 ***/ 'user' => [ 'identityClass' => 'common\models\backend\Admin', 'enableAutoLogin' => true, 'enableSession' => FALSE, // 關閉session // 'identityCookie' => ['name' => '_identity-api', 'httpOnly' => true], ], // 'session' => [ // 'name' => 'advanced-api', // ],
2. 獲取access token
-
認證類Admin
namespace common\models\backend; use Yii; use yii\web\IdentityInterface; /** * This is the model class for table "admin". * * @property int $id ID * @property string $username 用户名 * @property string $realname 姓名 * @property string $email 電子郵箱 * @property int $status 狀態 * @property string $password_hash 密碼 * @property string $auth_key 授權key * @property string $password_reset_token 密碼重置token * @property string $access_token 訪問token * @property int $expire_at 過期時間 * @property int $logged_at 登入時間 * @property int $created_at 創建時間 * @property int $updated_at 最後修改時間 */ class Admin extends \yii\db\ActiveRecord implements IdentityInterface { /** * {@inheritdoc} */ public static function tableName() { return 'admin'; } /** * {@inheritdoc} */ public function rules() { return [ [['id', 'email', 'password_hash', 'auth_key'], 'required'], [['id', 'status', 'expire_at', 'logged_at', 'created_at', 'updated_at'], 'integer'], [['username'], 'string', 'max' => 32], [['realname', 'email', 'password_hash', 'auth_key', 'password_reset_token', 'access_token'], 'string', 'max' => 255], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'username' => '用户名', 'realname' => '姓名', 'email' => '電子郵箱', 'status' => '狀態', 'password_hash' => '密碼', 'auth_key' => '授權key', 'password_reset_token' => '密碼重置token', 'access_token' => '訪問token', 'expire_at' => '過期時間', 'logged_at' => '登入時間', 'created_at' => '創建時間', 'updated_at' => '最後修改時間', ]; } public static function findIdentity($id) { // TODO: Implement findIdentity() method. } public static function findIdentityByAccessToken($token, $type = NULL) { // TODO: Implement findIdentityByAccessToken() method. } public function getId() { // TODO: Implement getId() method. } public function getAuthKey() { // TODO: Implement getAuthKey() method. } public function validateAuthKey($authKey) { // TODO: Implement validateAuthKey() method. } /** * 使用用户名查找用户 * * @param $username * @return \common\models\backend\Admin|null */ public static function findByUsername($username) { return static::findOne(['username' => $username]); } /** * 驗證密碼 * * @param string $password password to validate * @return bool if password provided is valid for current user */ public function validatePassword($password) { return Yii::$app->security->validatePassword($password, $this->password_hash); } /** * 生成access token * * @return string * @throws \yii\base\Exception */ public function generateAccessToken() { $this->access_token = Yii::$app->security->generateRandomString(); return $this->access_token; } }
-
控制器文件
namespace api\modules\backend\controllers; use api\models\backend\AdminLoginForm; class AdminController extends \yii\rest\ActiveController { public $modelClass = "common\models\backend\Admin"; /** * 用户登錄 * * @return \api\models\backend\AdminLoginForm|array * @throws \yii\base\Exception */ public function actionLogin() { $model = new AdminLoginForm(); $model->username = $_POST['username']; $model->password = $_POST['password']; if ($model->login()) { return ['access_token' => $model->login()]; } else { $model->validate(); return $model; } } }
-
後台用到的登錄表單模型類
namespace api\models\backend; use common\models\backend\Admin; use yii\base\Model; /** * 登錄表單 */ class AdminLoginForm extends Model { public $username; public $password; /** * @var Admin */ private $_user; /** * {@inheritdoc} */ public function rules() { return [ // username and password are both required [['username', 'password'], 'required'], // password is validated by validatePassword() ['password', 'validatePassword'], ]; } /** * @param $attribute * @param $params */ public function validatePassword($attribute, $params) { if (!$this->hasErrors()) { $user = $this->getUser(); if (!$user || !$user->validatePassword($this->password)) { $this->addError($attribute, 'Incorrect username or password.'); } } } /** * @return string|bool * @throws \yii\base\Exception */ public function login() { if ($this->validate()) { $accessToken = $this->_user->generateAccessToken(); $this->_user->save(); return $accessToken; } return FALSE; } /** * 查找用户 * * @return Admin|null */ protected function getUser() { if ($this->_user === NULL) { $this->_user = Admin::findByUsername($this->username); } return $this->_user; } }
3. 認證access token
-
修改每個controller
/** * 認證用户 access token * @return array */ public function behaviors() { return ArrayHelper::merge(parent::behaviors(),[ 'authenticatior' => QueryParamAuth::className() ]); } -
實現Admin類裏的findIdentityByAccessToken 方法
/** * 通過access token 獲取用户信息 * @param mixed $token * @param null $type * @return \common\models\backend\Admin|\yii\web\IdentityInterface|null */ public static function findIdentityByAccessToken($token, $type = NULL) { return static::findOne(['access_token'=>$token]); }