[英]Yii2: Simultaneous authentication between frontend and API
我已經把后端變成了一個 API。 並且 API 控制器具有 HttpBasicAuth 類型的身份驗證。
問題是,即使在前端進行身份驗證后,只要向 API 發出請求,就會出現身份驗證窗口。
我該怎么做才能在用戶在前端進行身份驗證時,在向 API 發出請求時不再請求訪問的用戶名和密碼?
API 中的控制器示例:
class CategoryController extends ActiveController
{
public $modelClass = 'api\models\Category';
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::className(),
'authMethods' => [
[
'class' => HttpBasicAuth::className(),
'auth' => function($username, $password) {
$out = null;
$user = \common\models\User::findByUsername($username);
if ($user != null) {
if ($user->validatePassword($password)) $out = $user;
}
return $out;
}
],
],
];
return $behaviors;
}
}
它被稱為共享會話。 它還取決於您的層級應用程序(前端和 api)是否都在同一個域中。 如果是,請按如下方式配置您的前端和 api 設置( <app>/frontend/config/main.php
和<app>/api/config/main.php
):
'components' => [
...
'request' => [
'csrfParam' => '_csrf-shared',
],
...
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => ['name' => '_identity-shared', 'httpOnly' => true],
],
...
'session' => [
'name' => 'advanced-shared',
],
...
這意味着您使用相同的名稱保存cookie和會話,以便當您在前端登錄並轉到后端/api時,后端端獲取相同的cookie,因此您將被檢測為經過身份驗證的用戶。
這里有一個重要的注意事項,為了使enableAutoLogin
對兩個層都有效,您應該為main-local.php
設置設置相同的cookieValidationKey
。 您可以手動設置它們,或編輯init.php
文件為所有層生成一個 cookieValidationKey。 (只要確保你知道你在做什么)。
順便說一句,我認為在frontend
和api
之間進行同時身份驗證不是一個好主意。 如果是frontend
和backend
那么它仍然可以忍受,但是與frontend
相比, api
交互是不同的。
我建議使用像Authorization: Bearer <token>
.. 你可以在這里得到更多信息Yii2 Rest Authentication
我假設這就是你所需要的.. 在common/components
文件夾中創建一個類,即ApiAuth
並粘貼以下代碼:
<?php
namespace common\components;
use yii\filters\auth\HttpBasicAuth;
class ApiAuth extends HttpBasicAuth
{
/**
* @inheritdoc
*/
public function authenticate($user, $request, $response)
{
if ($user->identity) {
return $user->identity;
}
return parent::authenticate($user, $request, $response);
}
}
這個類從yii\\filters\\auth\\HttpBasicAuth
擴展而來。 在調用瀏覽器提示之前,它會檢查是否填充了user->dentity
。 如果是這樣,則不需要提示。
在您的控制器行為中,將HttpBasicAuth
替換為ApiAuth
類:
use common\components\ApiAuth;
...
'authMethods' => [
[
'class' => ApiAuth::className(),
'auth' => function($username, $password) {
...
由於用戶已通過身份驗證,因此我只需為連接的用戶設置“AccessControl”。 如果他們沒有連接,他們將收到代碼 403 而不是 401。
這解決了這個問題:
class CategoryController extends ActiveController
{
public $modelClass = 'api\models\Category';
public function behaviors()
{
$behaviors = parent::behaviors();
$behaviors['access'] = [
'class' => \yii\filters\AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
],
],
];
return $behaviors;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.