什么是restful風格的api呢?我們之前有寫過大篇的文章來介紹其概念以及基本操作。
既然寫過了,那今天是要說點什么嗎?
這篇文章主要針對實際場景中api的部署來寫。
我們今天就來大大的侃侃那些年api遇到的授權驗證問題!獨家干活,如果看完有所受益,記得不要忘記給我點贊哦。
業(yè)務分析
我們先來了解一下整個邏輯
1.用戶在客戶端填寫登錄表單
2.用戶提交表單,客戶端請求登錄接口login
3.服務端校驗用戶的帳號密碼,并返回一個有效的token給客戶端
4.客戶端拿到用戶的token,將之存儲在客戶端比如cookie中
5.客戶端攜帶token訪問需要校驗的接口比如獲取用戶個人信息接口
6.服務端校驗token的有效性,校驗通過,反正返回客戶端需要的信息,校驗失敗,需要用戶重新登錄
本文我們以用戶登錄,獲取用戶的個人信息為例進行詳細的完整版說明。
以上,便是我們本篇文章要實現(xiàn)的重點。先別激動,也別緊張,分析好了之后,細節(jié)部分我們再一步一個腳印走下去。
準備工作
1.你應該有一個api應用.
2.對于客戶端,我們準備采用postman進行模擬,如果你的google瀏覽器還沒有安裝postman,請先自行下載
3.要測試的用戶表需要有一個api_token的字段,沒有的請先自行添加,并保證該字段足夠長度
4.api應用開啟了路由美化,并先配置post類型的login操作和get類型的signup-test操作
5.關閉了user組件的session會話
關于上面準備工作的第4點和第5點,我們貼一下代碼方便理解
- 'components'=> [
 - 'user'=> [
 - 'identityClass'=>'common/models/User',
 - 'enableAutoLogin'=> true,
 - 'enableSession'=> false,
 - ],
 - 'urlManager'=> [
 - 'enablePrettyUrl'=> true,
 - 'showScriptName'=> false,
 - 'enableStrictParsing'=> true,
 - 'rules'=> [
 - [
 - 'class'=>'yii/rest/UrlRule',
 - 'controller'=> ['v1/user'],
 - 'extraPatterns'=> [
 - 'POST login'=>'login',
 - 'GET signup-test'=>'signup-test',
 - ]
 - ],
 - ]
 - ],
 - // ......
 - ],
 
signup-test操作我們后面添加測試用戶,為登錄操作提供便利。其他類型的操作后面看需要再做添加。
認證類的選擇
我們在api/modules/v1/controllers/UserController中設定的model類指向 common/models/User類,為了說明重點這里我們就不單獨拿出來重寫了,看各位需要,有必要的話再單獨copy一個User類到api/models下。
校驗用戶權限我們以 yii/filters/auth/QueryParamAuth 為例
- useyii/filters/auth/QueryParamAuth;
 - publicfunctionbehaviors()
 - {
 - returnArrayHelper::merge (parent::behaviors(), [
 - 'authenticator'=> [
 - 'class'=> QueryParamAuth::className()
 - ]
 - ] );
 - }
 
如此一來,那豈不是所有訪問user的操作都需要認證了?那不行,客戶端第一個訪問login操作的時候哪來的token,yii/filters/auth/QueryParamAuth對外提供一個屬性,用于過濾不需要驗證的action。我們將UserController的behaviors方法稍作修改
- publicfunctionbehaviors()
 - {
 - returnArrayHelper::merge (parent::behaviors(), [
 - 'authenticator'=> [
 - 'class'=> QueryParamAuth::className(),
 - 'optional'=> [
 - 'login',
 - 'signup-test'
 - ],
 - ]
 - ] );
 - }
 
這樣login操作就無需權限驗證即可訪問了。
添加測試用戶
為了避免讓客戶端登錄失敗,我們先寫一個簡單的方法,往user表里面插入兩條數(shù)據(jù),便于接下來的校驗。
UserController增加signupTest操作,注意此方法不屬于講解范圍之內(nèi),我們僅用于方便測試。
- usecommon/models/User;
 - /**
 - * 添加測試用戶
 - */
 - publicfunctionactionSignupTest ()
 - {
 - $user=newUser();
 - $user->generateAuthKey();
 - $user->setPassword('123456');
 - $user->username ='111';
 - $user->email ='111@111.com';
 - $user->save(false);
 - return[
 - 'code'=> 0
 - ];
 - }
 
如上,我們添加了一個username是111,密碼是123456的用戶
登錄操作
假設用戶在客戶端輸入用戶名和密碼進行登錄,服務端login操作其實很簡單,大部分的業(yè)務邏輯處理都在api/models/loginForm上,來先看看login的實現(xiàn)
- useapi/models/LoginForm;
 - /**
 - * 登錄
 - */
 - publicfunctionactionLogin ()
 - {
 - $model=newLoginForm;
 - $model->setAttributes(Yii::$app->request->post());
 - if($user=$model->login()) {
 - if($userinstanceofIdentityInterface) {
 - return$user->api_token;
 - }else{
 - return$user->errors;
 - }
 - }else{
 - return$model->errors;
 - }
 - }
 
登錄成功后這里給客戶端返回了用戶的token,再來看看登錄的具體邏輯的實現(xiàn)
新建api/models/LoginForm.PHP
- namespaceapi/models;
 - useYii;
 - useyii/base/Model;
 - usecommon/models/User;
 - /**
 - * Login form
 - */
 - classLoginFormextendsModel
 - {
 - public$username;
 - public$password;
 - private$_user;
 - constGET_API_TOKEN ='generate_api_token';
 - publicfunctioninit ()
 - {
 - parent::init();
 - $this->on(self::GET_API_TOKEN, [$this,'onGenerateApiToken']);
 - } //Vevb.com
 - /**
 - * @inheritdoc
 - * 對客戶端表單數(shù)據(jù)進行驗證的rule
 - */
 - publicfunctionrules()
 - {
 - return[
 - [['username','password'],'required'],
 - ['password','validatePassword'],
 - ];
 
新聞熱點
疑難解答