摘要:最近在做認證功能,記錄整個過程,方便以后查看。請求參數當作請求參數發送,例如,由于大多數服務器都會保存請求參數到日志,這種方式應主要用于請求,因為它不能使用頭來發送使用者從認證服務器上獲取基于協議的,然后通過發送到服務器。
最近在做RESTful API認證功能,記錄整個過程,方便以后查看。本文參照了 https://segmentfault.com/a/1190000016368603部分內容,感謝該作者的分享,以下內容根據我的項目實際情況進行了調整。
認證介紹和Web應用不同,RESTful APIs 通常是無狀態的, 也就意味著不應使用 sessions 或 cookies, 因此每個請求應附帶某種授權憑證,因為用戶授權狀態可能沒通過 sessions 或 cookies 維護, 常用的做法是每個請求都發送一個秘密的 access token 來認證用戶, 由于 access token 可以唯一識別和認證用戶,API 請求應通過 HTTPS 來防止man-in-the-middle (MitM) 中間人攻擊.
認證方式HTTP 基本認證 :access token 當作用戶名發送,應用在access token可安全存在API使用端的場景, 例如,API使用端是運行在一臺服務器上的程序。
請求參數: access token 當作API URL請求參數發送,例如 https://example.com/users?acc..., 由于大多數服務器都會保存請求參數到日志, 這種方式應主要用于JSONP 請求,因為它不能使用HTTP頭來發送 access token
OAuth 2 : 使用者從認證服務器上獲取基于 OAuth2 協議的 access token, 然后通過 HTTP Bearer Tokens 發送到 API 服務器。
上方進行簡單介紹,內容來自 Yii Framework 2.0 權威指南
實現步驟繼續上一篇 的內容(這里暫時使用默認User數據表,正式環境請分離不同的數據表來進行認證)
需要添加的數據內容繼上篇的 User 數據表,我們還需要增加一 個 access_token 和 expire_at 的字段,
進入項目根目錄打開控制臺輸入以下命令:
./yii migrate/create add_column_access_token_to_user ./yii migrate/create add_column_expire_at_to_user
打開 你的項目目錄 /console/migrations/m181224_075747_add_column_access_token_user.php 修改如下內容:
public function up() { $ret = $this->db->createCommand("SELECT * FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = "user" AND column_name = "access_token"")->queryOne();//判斷user表是否有"access_token"這個字段 if (empty($ret)) { $this->addColumn("user", "access_token", $this->string(255)->defaultValue(NULL)->comment("令牌")); } } public function down() { $this->dropColumn("user", "access_token"); return true; }
打開 你的項目目錄 /console/migrations/m181224_092333_add_column_expire_at_user.php 修改如下內容:
public function up() { $ret = $this->db->createCommand("SELECT * FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = "user" AND column_name = "expire_at"")->queryOne(); if (empty($ret)) { $this->addColumn("user", "expire_at", $this->integer(11)->defaultValue(NULL)->comment("令牌過期時間")); } } public function down() { $this->dropColumn("user", "expire_at"); return true; }
執行遷移命令
./yii migrate配置
打開 apiconfigmain.php
配置 user 應用組件:
"user" => [ "identityClass" => "apimodelsUser", "enableAutoLogin" => true, "enableSession"=>false, //"identityCookie" => ["name" => "_identity-api", "httpOnly" => true], ],
將 session 組件注釋掉,或刪掉
// "session" => [ // // this is the name of the session cookie used for login on the backend // "name" => "advanced-api", // ],
編寫 apimodelsUser.php 實現認證類,繼承 IdentityInterface
將 commonmodelsUser 類拷貝到 apimodels 目錄下,修改命名空間為 apimodels
將 commonmodelsLoginForm.php 類拷貝到 apimodels* 目錄下,修改命名空間,并重寫 login* 方法:
validate()) { //return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0); if ($this->getUser()) { $access_token = $this->_user->generateAccessToken(); $this->_user->expire_at = time() + static::EXPIRE_TIME; $this->_user->save(); Yii::$app->user->login($this->_user, static::EXPIRE_TIME); return $access_token; } } return false; }上方代碼給 User 模型添加了一個 generateAccessToken() 方法,因此我們到 apimodelsUser.php 中添加此方法
namespace apimodels; use Yii; use yiiaseNotSupportedException; use yiiehaviorsTimestampBehavior; use yiidbActiveRecord; use yiiwebIdentityInterface; use yiiwebUnauthorizedHttpException; ... ... class User extends ActiveRecord implements IdentityInterface { ... ... /** * 生成accessToken字符串 * @return string * @throws yiiaseException */ public function generateAccessToken() { $this->access_token=Yii::$app->security->generateRandomString(); return $this->access_token; } }接下來在apicontrollers新加一個控制器 命名為 UserController 并繼承 yii estActiveController,編寫登錄 Login 方法,具體代碼如下:
namespace apicontrollers; use apimodelsLoginForm; use yii estActiveController; use yii; class UserController extends ActiveController { public $modelClass = "apimodelsUser"; public function actions() { $action= parent::actions(); // TODO: Change the autogenerated stub unset($action["index"]); unset($action["create"]); unset($action["update"]); unset($action["delete"]); } public function actionIndex() { //你的代碼 } /** * 登陸 * @return array * @throws yiiaseException * @throws yiiaseInvalidConfigException */ public function actionLogin() { $model = new LoginForm(); if ($model->load(Yii::$app->getRequest()->getBodyParams(), "") && $model->login()) { return [ "access_token" => $model->login(), ]; } else { return $model->getFirstErrors(); } } }最后新增一條 URL 規則
打開 apiconfigmain.php 修改 components 屬性,添加下列代碼:
"urlManager" => [ "enablePrettyUrl" => true, "enableStrictParsing" => true, "showScriptName" => false, "rules" => [ ["class" => "yii estUrlRule", "controller" => "user", "extraPatterns"=>[ "POST login"=>"login", ], ], ], ]使用一個調試工具來進行測試 http://youdomain/users/login 記住是POST 請求發送,假如用POSTMAN有問題的話指定一下 Content-Type:application/x-www-form-urlencoded 。
維持認證狀態
ok,不出意外的話,相信你已經可以收到一個access_token 了,接下來就是如何使用這個token,如何維持認證狀態,達到不攜帶這個token將無法訪問,返回 401實現認證步驟:
在你的 REST 控制器類中配置 authenticator 行為來指定使用哪種認證方式
在你的 user identity class 類中實現 yiiwebIdentityInterface::findIdentityByAccessToken() 方法.
具體實現方式如下:
打開之前的 User 控制器( apicontrollersUserController.php ),增加以下內容:
use yiihelpersArrayHelper; use yiifiltersauthQueryParamAuth; ...//此處省略一些代碼了 public function behaviors() { return ArrayHelper::merge(parent::behaviors(), [ "authenticatior" => [ "class" => QueryParamAuth::className(), //實現access token認證 "except" => ["login"], //無需驗證access token的方法,注意區分$noAclLogin ] ]); } ...實現 findIdentityByAccessToken() 方法:
打開 apimodelsUser.php 重寫 findIdentityByAccessToken() 方法
... use yiiwebUnauthorizedHttpException; ... class User extends ActiveRecord implements IdentityInterface { ... ... /** * {@inheritdoc} */ public static function findIdentityByAccessToken($token, $type = null) { // throw new NotSupportedException(""findIdentityByAccessToken" is not implemented."); $user = static::find()->where(["access_token" => $token, "status" => self::STATUS_ACTIVE])->one(); if (!$user) { return false; } if ($user->expire_at < time()) { throw new UnauthorizedHttpException("the access - token expired ", -1); } else { return $user; } } ... }打開 apicontrollersUserController.php ,增加 Test方法,用于測試令牌驗證
public function actionTest() { return ["status"=>"success"]; }修改 apiconfigmain.php
"urlManager" => [ "enablePrettyUrl" => true, "enableStrictParsing" => true, "showScriptName" => false, "rules" => [ ["class" => "yii estUrlRule", "controller" => "user", //"pluralize" => false, //設置為false 就可以去掉復數形式了 "extraPatterns"=>[ "GET test"=>"test", "POST login"=>"login", ], ], ], ]接下來訪問一下你的域名 http://youdomain/users/test,不攜帶任何參數是不是返回 401了?
ok,這里介紹兩種訪問方式,一種是URL訪問,另一種是通過header 來進行攜帶http://youdomain/users/test?a...
傳遞 header 頭信息
Authorization:Bearer YYdpiZna0hJGhjsfqwxUeHEgLDfHEjB-注意 Bearer 和你的token中間是有 一個空格的,很多同學在這個上面碰了很多次
以上就是基于YII2.0 RESTful 認證的內容。本文參照了 https://segmentfault.com/a/1190000016368603部分內容,感謝該作者的分享,以上內容根據我的項目實際情況進行了調整。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/29855.html
摘要:之速率限制什么是速率限制權威指南翻譯過來為限流,為防止濫用,你應該考慮對您的限流。如果在規定的時間內接收了一個用戶大量的請求,將返回響應狀態代碼這意味著過多的請求。 Yii2.0 RESTful API 之速率限制 什么是速率限制? 權威指南翻譯過來為限流,為防止濫用,你應該考慮對您的 API 限流。 例如,您可以限制每個用戶 10 分鐘內最多調用 API 100 次。 如果在規定的時...
摘要:請求參數當作請求參數發送,例如,由于大多數服務器都會保存請求參數到日志,這種方式應主要用于請求,因為它不能使用頭來發送使用者從認證服務器上獲取基于協議的,然后通過發送到服務器。 認證介紹 和Web應用不同,RESTful APIs 通常是無狀態的, 也就意味著不應使用 sessions 或 cookies, 因此每個請求應附帶某種授權憑證,因為用戶授權狀態可能沒通過 sessions ...
摘要:在本教程中,我們將了解如何在應用中使用認證。當用戶通過登錄時,會生成令牌并將其發送給用戶,該用戶可用于身份驗證。提供,可以毫無困難地使用認證。服務提供者我們使用的最新版本,它可以使用包發現并自動注冊服務。 showImg(https://segmentfault.com/img/remote/1460000019095408?w=1000&h=526); 在本教程中,我們將了解如何在 ...
摘要:之版本控制之前我寫過兩篇關于如何搭建,以及認證等處理,但是沒有涉及到版本管理,今天就來談談版本管理如何實現。如果你還沒有安裝,你可以按照這里的說明進行安裝。 Yii2.0 RESTful API 之版本控制 之前我寫過兩篇關于 Yii2.0 RESTful API 如何搭建,以及 認證 等處理,但是沒有涉及到版本管理,今天就來談談版本管理如何實現。 索性就從頭開始一步一步搭建吧,但是關...
showImg(https://segmentfault.com/img/bV6aHV?w=1280&h=800); 社區優秀文章 Laravel 5.5+passport 放棄 dingo 開發 API 實戰,讓 API 開發更省心 - 自造車輪。 API 文檔神器 Swagger 介紹及在 PHP 項目中使用 - API 文檔撰寫方案 推薦 Laravel API 項目必須使用的 8 個...
閱讀 1470·2019-08-30 15:55
閱讀 1172·2019-08-30 15:52
閱讀 1282·2019-08-29 13:53
閱讀 1465·2019-08-29 11:19
閱讀 2964·2019-08-26 13:29
閱讀 527·2019-08-26 11:33
閱讀 2587·2019-08-23 17:20
閱讀 1022·2019-08-23 14:14