evgenidev/yii2-oauth2

Simple PHP OAuth2 Server for Yii2

Installs: 145

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 0

Type:yii2-extension

1.0.0 2021-12-01 17:56 UTC

This package is auto-updated.

Last update: 2024-04-29 04:41:08 UTC


README

Installation

The preferred way to install this extension is through composer.

Either run:

php composer.phar require --prefer-dist evgenidev/yii2-oauth2 "*"

or add:

"evgenidev/yii2-oauth2": "*"

to the require section of your composer.json.

To use this extension, add the following code in your application configuration:

'modules' => [
    'oauth2' => [
        'class' => \EvgeniDev\Yii2\OAuth2\Module::class,
        'accessTokenLifetime' => 3600 * 12,
        'identityClass' => \app\models\User::class,
    ],
],

Also add bootstrap param:

'bootstrap' => [
    'oauth2',
],

If you want to add a custom authorize view file simple add a authorizeView parameter to oauth2 module.

'modules' => [
    'oauth2' => [
        'class' => \EvgeniDev\Yii2\OAuth2\Module::class::class,
        'accessTokenLifetime' => 3600 * 12,
        'identityClass' => \app\models\User::class,
        'authorizeViewPath' => '@app/views/your_view',
        'layout' => '@app/views/your_layout',
    ],
],

The basic authorize view you can find here:

./vendor/evgenidev/yii2-oauth2/src/views/authorize/index.php

For SPA application you should configure spaApp parameter. By default, you will get a response from server on json format. If you need other response format, you can add a responseFormat parameter:

use yii\web\Response;

'modules' => [
    'oauth2' => [
        'class' => \EvgeniDev\Yii2\OAuth2\Module::class,
        'accessTokenLifetime' => 3600 * 12,
        'identityClass' => \app\models\User::class,
        'spaApp' => true,
        'responseFormat' => Response::FORMAT_XML,
    ],
],

Create a migration in your project and expend from \EvgeniDev\Yii2\OAuth2\Migrations\Oauth.

use EvgeniDev\Yii2\OAuth2\Migrations\OAuth2;

/**
 * Your oauth migration.
 */
class m191117_223223_oauth extends OAuth2
{

}

This migration creates the oauth2 database scheme and insert test data.

Apply migration.

On the next step you should add url rule to urlManager, like this:

'urlManager' => [
    'rules' => [
        'oauth2/authorize' => 'oauth2/authorize',
        'oauth2/access_token' => 'oauth2/access-token',
    ],
],

Usage

It is simple to add a new OAuth client. Use a command:

./yii oauth2/default/create-client http://redirect.com clientName

GET request example to get a code:

https://yoursite.com/oauth/authorize?response_type=code&client_id=clientID&state=someState&redirect_uri=http://site.com/url

With redirect response:

http://site.com/url?code=gjkmo5ufhvkdmjgnbdJklsdfFQPfdfg456nfdsjfnjsdnf&state=someState

After that you need to do a POST request with params like:

https://yoursite.com/oauth/access_token

"grant_type": "authorization_code"
"code": "gjkmo5ufhvkdmjgnbdJklsdfFQPfdfg456nfdsjfnjsdnf"
"client_id": "testClientID"
"client_secret": "testClientSecret"
"redirect_uri": "http://site.com/url"

If user is unauthorized, module will redirect to Yii::$app->user->loginUrl with GET param redirectUrl:

https://yoursite.com/loginUrl?redirectUrl=xxx

So you can redirect user to a redirectUrl after success authorization.

If you want to control OAuth2 server through the interface (admin and etc.), you can find all necessary models to do that in:

./vendor/evgenidev/yii2-oauth2/Records/*

and

./vendor/evgenidev/yii2-oauth2/Services/*

To use this extension, simply add the behaviors for your base controller:

use yii\helpers\ArrayHelper;
use yii\filters\auth\CompositeAuth;
use yii\filters\auth\HttpBearerAuth;
use yii\filters\auth\QueryParamAuth;

class Controller extends \yii\rest\Controller
{
    /**
     * {@inheritDoc}
     */
    public function behaviors()
    {
        return ArrayHelper::merge(parent::behaviors(), [
            'authenticator' => [
                'class' => CompositeAuth::class,
                'authMethods' => [
                    ['class' => HttpBearerAuth::class],
                    ['class' => QueryParamAuth::class, 'tokenParam' => 'accessToken'],
                ],
            ],
        ]);
    }
}

To identify a client you can use a function findIdentityByAccessToken() in your User identity AR model:

use EvgeniDev\Yii2\OAuth2\Records\OAuthAccessToken;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

/**
 * User AR model.
 */
class User extends ActiveRecord implements IdentityInterface
{
    /**
     * {@inheritDoc}
     */
    public static function findIdentityByAccessToken($token, $type = null)
    {
        $oauthToken = OAuthAccessToken::find()
            ->byAccessToken($token)
            ->one();
    
        if ($oauthToken === null || $oauthToken->getExpiresAt() < date('Y-m-d H:i:s')) {
            return null;
        }
    
        return self::find()
            ->where(['id' => $oauthToken->getUserID()])
            ->one();
    }
}