簡體   English   中英

Yii2:前端和 API 之間的同步認證

[英]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。 (只要確保你知道你在做什么)。

順便說一句,我認為在frontendapi之間進行同時身份驗證不是一個好主意。 如果是frontendbackend那么它仍然可以忍受,但是與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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM