Страница 1 из 1

Авторизация при помощи сторонних API

Добавлено: 2017.01.09, 17:06
rkk
Доброго времени суток всем.

Есть такая задача, авторизировать пользователя в системе у которого нет учетной записи.
Есть сторонние API которым я должен передать логин, email, пароль они мне возвращают статус разрешен или запрещен этому пользователю доступ (некий параметр authorize 1 или 0).
Далее я должен послать некий код на email, пользователь должен его получить и ввести в соответствующее поле, я его проверяю если оно совпало с отправленным пускаю в систему. Давайте для простоты без email т.е. Если authorize = 1 даю доступ в систему иначе нет.

По сути мне надо сказать yii, что

Код: Выделить всё

Yii::$app->user->isGuest = false;
и, желательно,

Код: Выделить всё

Yii::$app->user->identity->id = логин или email
(в данном случае не важно возможно в API можно будет забрать некий идентификатор пользователя)

Начал ковырять

Код: Выделить всё

return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600 * 24 * 30 : 0);
стандартной авторизации, запутался, и мой мозг перестал воспринимать информацию. :?

Подскажите как действовать в подобной ситуации? Может у кого какие идеи есть?
Да и после авторизации никакой учетной записи в таблице user не должно создаваться.
На данный момент роли не интересуют интересует возможность дать доступ пользователю к модулю и не давать.
Нужна любая помощь! :)

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.09, 17:26
samdark
Вам необходимо реализовать свой Identity, но при этом использовать сторонний сервис вместо базы.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.09, 17:49
rkk
А если не затруднит. Какие исходники посмотреть (пути к файлам)? Или в данном случае не стоит опираться на стандартный функционал Yii и написать свой модуль Типа MyUser::isGuest() и MyUser::getId()? Но какой то велосипед получается.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.09, 19:46
samdark

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.10, 15:44
rkk
Спасибо, большое! :)
Так понятнее стало куда двигаться.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.11, 17:51
rkk
У меня в common config определен компонент

Код: Выделить всё

    'components' => [
        'user' => [
            'identityClass' => 'yii\web\User',
            'enableAutoLogin' => true,
//            'on '.\yii\web\User::EVENT_BEFORE_LOGIN => ['\common\models\User', 'beforeLogin'],
            'on '.\yii\web\User::EVENT_AFTER_LOGIN => ['\common\models\User', 'afterLogin']
        ],        
    ],
соответственно в '\common\models\User' определенна функция 'afterLogin'
а в frontend config

Код: Выделить всё

    'components' => [
        'user' => [
            'identityClass' => 'frontend\modules\account\models\User',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
        ],
    ],
логика 'frontend\modules\account\models\User' полностью отличается от '\common\models\User'
и в frontend\modules\account\models\User мне ненужно выполнять действия 'afterLogin'.
Но после успешной авторизации (авторизация выполняется в frontend части) выполняется действие 'afterLogin' из '\common\models\User'.

Если я в frontend\modules\account\models\User определяю событие 'afterLogin'

Код: Выделить всё

	public static function afterLogin($event)
    {
    }	
'afterLogin' из '\common\models\User' все равно выполняется.
Если прописать return true; то 'afterLogin' из '\common\models\User' уже не выполняется

Код: Выделить всё

	public static function afterLogin($event)
    {
        return true;
    }	
Правильно ли я сделал? "терзают меня смутные сомнения".

Как мне сделать, что бы не выполнялось 'afterLogin' из '\common\models\User'? когда я использую авторизация frontend части

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.11, 21:28
samdark
Как мне сделать, что бы не выполнялось 'afterLogin' из '\common\models\User'? когда я использую авторизация frontend части
Если классы разделены, ничего выполняться не должно.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.12, 09:34
rkk
А что значит "разделены", как это определить?
один определен в папке frontend/config

Код: Выделить всё

    'components' => [
        'user' => [
            'identityClass' => 'frontend\modules\account\models\User',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
        ],
    ],
другой определен в папке common/config

Код: Выделить всё

    'components' => [
        'user' => [
            'identityClass' => 'yii\web\User',
            'enableAutoLogin' => true,
//            'on '.\yii\web\User::EVENT_BEFORE_LOGIN => ['\common\models\User', 'beforeLogin'],
            'on '.\yii\web\User::EVENT_AFTER_LOGIN => ['\common\models\User', 'afterLogin']
        ],        
    ],
то что определенно в common действует и на frontend и backend части, верно?
получается строкой
'on '.\yii\web\User::EVENT_AFTER_LOGIN => ['\common\models\User', 'afterLogin']
я передаю выполнение события в '\common\models\User', 'afterLogin'?
но вопрос все равно остается.
Как мне сделать, что бы не выполнялось 'afterLogin' из '\common\models\User'? :(

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.12, 13:57
samdark
Ну, убрать 'on '.\yii\web\User::EVENT_AFTER_LOGIN => ['\common\models\User', 'afterLogin'] из общего конфига с сунуть туда, где это нужно.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.12, 15:14
rkk
Спасибо, попробую разделить, пока нужно в обоих частях.
на данный момент я в afterLogin поставил проверку из какого класса было вызвано событие.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.13, 17:51
rkk
В common\models\LoginForm изменил функцию login

Код: Выделить всё

	public function login()
    {
        if ($this->validate()) {
            return Yii::$app->user->login($this->getUser(), 0);
        } else {
            return false;
        }
    }
насколько я понял в return Yii::$app->user->login($this->getUser(), 0); последний параметр $duration = 0 указывает на то что бы не запоминать пользователя.
Когда я закрываю браузер и открываю заново, то пользователь оказывается авторизованным, т.е. Имеет доступ к админке.
Собственно 2 вопроса.
1) как сделать что бы после закрытия браузера авторизация сбрасывалась? Т.е. после открытия браузера пользователь должен заново
авторизоваться.
2) Как сделать так чтобы авторизация действовала ограниченно время? Т.е. после авторизации, не зависимо от того пользователь что-то делал на сайте или нет, по истечении 30 минут авторизация сбрасывалась и пользователь должен по новой авторизоваться.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.13, 18:42
rak
1. при закрытии браузера он на самом деле не закрывается, а висит в памяти :)
2. в конфиге нужно вот так настроить компоненты

Код: Выделить всё

'user'  => [
    'enableAutoLogin' => false,
],
'session'  => [
     'timeout' => 60 * 30,
],

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.14, 13:19
samdark
Это всё Chrome. По спецификации он обязан при закрытии убивать сессию, но не делает этого.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.01.16, 12:43
rkk
Вот нашел! ;)

Код: Выделить всё

        'user' => [
            'enableAutoLogin' => false,
            'absoluteAuthTimeout' => 30, // время работы пользователя
        ],
В данном случае пользователь может проработать 30 секунд.
samdark писал(а): 2017.01.14, 13:19 Это всё Chrome. По спецификации он обязан при закрытии убивать сессию, но не делает этого.
Да, действительно только Chrome этим страдает. А какие есть варианты, может есть у кого-то решение?
Может написать JS для закрытия окна который будет вызывать logout, принудительно?

Re: Авторизация при помощи сторонних API

Добавлено: 2017.02.03, 12:34
rkk
Можно ли использовать две авторизации для фронтент части?
т.е. есть авторизация user переработанная, рабочая.
frontend/config/main.php

Код: Выделить всё

        'user' => [
            'identityClass' => 'frontend\modules\account\models\User',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
        ],
я хочу сделать еще одну авторизацию для отдельного модуля и/или для той же фронтент части (разделение на роли не планируется).
я написал модуль 'frontend\modules\account\models\Client', он практически идентичен 'identityClass' => 'frontend\modules\account\models\User',
когда в конфиге пишу (дописываю)

Код: Выделить всё

        'client' => [
            'identityClass' => 'frontend\modules\account\models\Client',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
        ],
сайт мне возвращает:
Invalid Configuration – yii\base\InvalidConfigException

The configuration for the "client" component must contain a "class" element.
если пишу

Код: Выделить всё

        'user' => [
            'identityClass' => 'frontend\modules\account\models\Client',
            'enableAutoLogin' => true,
            'identityCookie' => ['name' => '_identity-frontend', 'httpOnly' => true],
        ],
получается 'frontend\modules\account\models\Client' работает.
как добавить еще авторизацию 'client'?

Re: Авторизация при помощи сторонних API

Добавлено: 2017.02.03, 12:45
Nex-Otaku
Компонент "user" относится к "основным компонентам" Yii, поэтому класс для него указывается автоматически при старте приложения - по имени "user".

Вам для копирования "user" нужно указать в компоненте "client" тот же класс.

Код: Выделить всё

'class' => 'yii\web\User',
Но этим всё не ограничится - вам же как-то надо авторизацию разделять, для этого куки должны быть разные. И так далее.

Re: Авторизация при помощи сторонних API

Добавлено: 2017.02.03, 15:48
rkk
Спасибо большое, помогло, буду дальше разбираться.