Yii2: одновременная аутентификация между интерфейсом и API - PullRequest
0 голосов
/ 22 октября 2018

Я превратил бэкэнд в 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;
    }
}

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Поскольку пользователь уже аутентифицирован, тогда я просто установил «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;
    }
}
0 голосов
/ 22 октября 2018

Это называется сеансами обмена.Это также зависит от того, находятся ли ваши приложения уровня (веб-интерфейс и 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 и сеанс с тем же именем, чтобы при входе в веб-интерфейси перейдите к backend / api, серверная сторона извлекает те же куки, поэтому вы будете обнаружены как аутентифицированный пользователь.

Здесь одно важное замечание, чтобы enableAutoLogin работало на обоих уровнях, вы должны установитьодинаковые cookieValidationKey для обеих main-local.php настроек.Вы можете просто установить их вручную или отредактировать файл init.php, чтобы сгенерировать один cookieValidationKey для всех уровней.(Просто убедитесь, что вы знаете, что делаете).

Кстати, я думаю, что не стоит делать одновременную аутентификацию между frontend и api.Если это frontend и backend, то это все еще терпимо, но взаимодействие api отличается от frontend.
Я предлагаю использовать заголовки, такие как Authorization: Bearer <token> .. Вы можете получить больше информации об этом здесь Аутентификация Yii2 Rest

Обновление

Я полагаю, это то, что вам нужно. Создайте класс, например ApiAuth в папке common/components и вставьте следующий код:

<?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 class:

use common\components\ApiAuth;
...
'authMethods' => [
    [
        'class' => ApiAuth::className(),
        'auth' => function($username, $password) {
        ...
...