venveo/craft-oauthclient

简单的OAuth 2.0客户端

安装次数: 6,008

依赖项: 3

建议者: 0

安全: 0

星级: 9

关注者: 4

分支: 3

开放问题: 19

类型:craft插件

2.1.9 2021-03-31 00:43 UTC

This package is auto-updated.

Last update: 2024-09-15 19:27:32 UTC


README

此插件为开发者提供了一种简单集中化的方法来管理和存储OAuth 2.0客户端和令牌。

它提供了一个易于使用的API和前端,用于授权令牌以执行内部业务逻辑。但它不会作为认证提供者,让用户登录到CMS。

特性

  • 用于集成League OAuth提供者的简单API
  • 为开发者提供大量事件
  • 用于刷新令牌的CLI
  • 项目配置支持
  • 在您的模块中生成认证UI的一行Twig辅助工具

示例用例

  • 构建自定义CRM集成
  • 从Google Sheets读取和写入
  • 查询企业Facebook页面上的数据

示例非用例

  • 在前端登录用户
  • 允许用户通过社交账户访问CP
  • 跟踪许多CMS用户的社交账户

要求

此插件应在Craft CMS 3.1.34.3或更高版本上运行

安装

要安装插件,请按照以下说明操作。

  1. 打开您的终端并转到您的Craft项目

     cd /path/to/project
    
  2. 然后告诉Composer加载插件

     composer require venveo/craft-oauthclient
    
  3. 在控制面板中,转到设置→插件,并点击OAuth 2.0客户端的“安装”按钮。

  4. 在Craft设置页面上配置

提供者

在此上下文中,提供者是一个通过令牌授权公开API的OAuth 2.0服务器。默认情况下,此插件附带以下提供者

  • Google
  • Facebook
  • GitHub

插件利用了由thephpleague广泛使用的oauth2-client项目,以尽可能轻松地添加提供者。我们为此抽象添加了一个额外的层,以混合Craft的要求。

创建提供者

假设您的服务已经存在一个League提供者,您可以轻松地创建自己的实现。在您的模块或插件中,为提供者创建一个文件并遵循以下大纲

<?php
use League\OAuth2\Client\Provider\YOUR_PROVIDER_CLASS as LeagueProvider;
use venveo\oauthclient\base\Provider;
class MyProvider extends Provider
{
    /**
     * @inheritDoc
     */
    public static function displayName(): string
    {
        // This is what is displayed in the CP when registering an App
        return 'My Provider';
    }

    public static function getProviderClass(): string
    {
        // Return the class name for the league provider
        return LeagueProvider::class;
    }
}

现在您只需在插件或模块的初始化函数中注册它

```php
<?php
use venveo\oauthclient\services\Providers;
use craft\events\RegisterComponentTypesEvent;
use MyProvider;
// [...]
Event::on(Providers::class, Providers::EVENT_REGISTER_PROVIDER_TYPES, function (RegisterComponentTypesEvent $event) {
    $event->types[] = MyProvider:class
});

一旦注册了提供者,您点击“注册新应用”时,它就会出现在控制面板的提供者下拉列表中。

上面的示例是注册提供者的基本方法。如果您需要,有许多方法可以覆盖和实现,以根据需要自定义提供者的授权流程。

有关此处的可能性,请参阅venveo\oauthclient\base\Provider

应用

在此插件中,应用表示已注册OAuth提供者的提供者的实现。大多数人可能只需要一个或两个,但您可以根据需要创建任意多个。要注册应用,您需要从提供者的网站开发选项开始,并创建一个OAuth 2.0应用程序。在某个时候,您将被要求提供登录流程的重定向URI。此URI由插件在应用注册后生成。您需要将其设置为临时值,直到保存应用 - 在此点,您需要将其更新为提供者。

在应用程序注册后,您应该能够访问OAuth应用程序概览页面,并单击应用程序列表右侧的“+”按钮来创建您的第一个令牌。

API使用

此插件假定您在模块或插件中执行实际逻辑。

该插件提供了以下服务

  • venveo\oauthclient\services\Apps - 用于检索应用程序及其配置
  • venveo\oauthclient\services\Credentials - 用于检索和管理应用程序的令牌
  • venveo\oauthclient\services\Providers - 用于管理可用的提供者
  • venveo\oauthclient\services\Tokens - 用于管理令牌

通常,您只会使用AppsCredentials服务。

控制认证流程

通常,您可能需要根据具体情况调整认证过程提供者的参数。例如,在某些情况下,您可能希望强制Google提示同意,以便您可以从先前认证的个人那里获取刷新令牌。如果您希望在用户通过应用程序的过程中调整请求的作用域,这也可能很有用。

通常,这可能意味着编写大量的重复代码;然而,我们通过在认证过程中引入“上下文”来解决这个问题。例如,我可能会使用Twig助手在我的模块中渲染一个连接器,并确保用户能够离线访问Google。我首先会使用上下文参数渲染我的连接器,然后在模块中注册事件处理程序来根据上下文调整认证URL。

控制面板中应用程序列表上的连接按钮的上下文是plugin.cp

见示例

事件

venveo\oauthclient\services\Apps

  • Apps:EVENT_BEFORE_APP_SAVED
    • venveo\oauthclient\events\AppEvent
  • Apps:EVENT_AFTER_APP_SAVED
    • venveo\oauthclient\events\AppEvent
  • Apps:EVENT_BEFORE_APP_DELETED
    • venveo\oauthclient\events\AppEvent
  • Apps:EVENT_AFTER_APP_DELETED
    • venveo\oauthclient\events\AppEvent
  • Apps:EVENT_GET_URL_OPTIONS
    • venveo\oauthclient\events\AuthorizationUrlEvent

venveo\oauthclient\services\Tokens

  • Tokens:EVENT_BEFORE_TOKEN_SAVED
    • venveo\oauthclient\events\TokenEvent
  • Tokens:EVENT_BEFORE_TOKEN_SAVED
    • venveo\oauthclient\events\TokenEvent

venveo\oauthclient\services\Credentials

  • Credentials:EVENT_BEFORE_REFRESH_TOKEN
    • venveo\oauthclient\events\TokenEvent
  • Credentials:EVENT_AFTER_REFRESH_TOKEN
    • venveo\oauthclient\events\TokenEvent
  • Credentials::EVENT_TOKEN_REFRESH_FAILED
    • venveo\oauthclient\events\TokenEvent

venveo\oauthclient\base\Provider

  • venveo\oauthclient\base\Provide::EVENT_CREATE_TOKEN_MODEL_FROM_RESPONSE
    • venveo\oauthclient\events\TokenEvent

venveo\oauthclient\controllers\AuthorizeController

  • venveo\oauthclient\controllers\AuthorizeController::EVENT_BEFORE_AUTHENTICATE
    • venveo\oauthclient\events\AuthorizationEvent
  • venveo\oauthclient\controllers\AuthorizeController::EVENT_AFTER_AUTHENTICATE
    • venveo\oauthclient\events\AuthorizationEvent

Twig变量

OAuth客户端插件提供了一个有用的Twig变量craft.oauth,可以帮助您构建您的UI。

craft.oauth.getAppByHandle('handle')如果存在,则返回App模型

命令行界面(CLI)

如果您想要刷新所有令牌,可以利用CLI来自动化此过程。

./craft oauthclient/apps/refresh-tokens <app handle>

如果存在错误,则返回状态码1,如果成功则返回0

示例

与Google Sheets交互

如果您想在Google Sheets账户中管理一些数据,可以轻松地要求Google_Client composer包并发出必要的请求;然而,令牌管理会增加很多开销和复杂性。这正是此插件发挥作用的地方。假设您已经包含了Google_Client,您可以像这样使用此插件

```php
use venveo\oauthclient\Plugin;
// [...]

// Get the plugin instance. Note: make sure you do this after the application has been inited, such as in a route or
// event.
$plugin = Plugin::$plugin;
// Let's grab a valid token - we could pass the current user ID in here to limit it
$tokens = $plugin->credentials->getValidTokensForAppAndUser('google');
// Get the app from the apps service
$app = $plugin->apps->getAppByHandle('google');

// Show time! Note: you should add some error checking.
$client = new Google_Client();
$client->setAccessToken($tokens[0]->accessToken);
$client->setClientId($app->getClientId());
$client->setClientSecret($app->getClientSecret());

$service = new Google_Service_Sheets($client);
$sheet = $service->spreadsheets->get('some-google-sheet');

使用Twig变量检查当前用户是否已连接

{% set app = craft.oauth.getAppByHandle('google') %}
{% if app %}
    {{ app.name }}
    {% set tokens = app.getValidTokensForUser() %}
    {% if tokens|length %}
        Connected!
    {% else %}
        {# This will render some boilerplate UI to connect the app #}
        {{ app.renderConnector() }}
    {% endif %}
{% else %}
    Could not find app
{% endif %}

有条件地修改认证流程

示例1:修改OAuth提供者设置

在此示例中,我们将使用上下文渲染连接器并注册事件以在渲染连接URL之前修改授权参数。

{% set app = craft.oauth.getAppByHandle('google') %}
{{ app.renderConnector('cp') }}

{# I can also just render the link URL #}
{# Note: As of 2.1.9, a return URL may be sent as a paramter in getRedirectUrl() #}
<a href="{{ app.getRedirectUrl('cp', craft.app.request.url) }}">Login</a>
use venveo\oauthclient\events\AuthorizationUrlEvent;
use venveo\oauthclient\services\Apps;
use yii\base\Event;
// [...]
Event::on(Apps::class, Apps::EVENT_GET_URL_OPTIONS, function (AuthorizationUrlEvent $e) {
    if ($e->context === 'cp' && $e->app->handle === 'google') {
        // Force re-consent during OAuth 
        $e->options['prompt'] = 'consent';
        $e->options['access_type'] = 'offline';
        $e->options['approval_prompt'] = null;
    }
});

示例2:根据上下文修改OAuth流程

如果我们想要调整用户认证后跳转的返回URL,我们有两种方法。第一种方法非常简单,使用了标准的Craft表单重定向。

<form method="post" action="{{ app.getRedirectUrl(context) }}">
        {{ csrfInput() }}
        {# In this case, we'll just send the user back to this page #}
        {{ redirectInput(craft.app.request.url) }}
        <button type="submit" class="btn formsubmit">Connect</button>
</form>

第二种情况更复杂,这时候我们没有表单,而只是有一个指向 app.getRedirectUrl() 的按钮。

由于这不是POST请求,我们需要使用 context 来修改流程。我们将我们的上下文命名为 "my-custom-context",并使用该上下文调用重定向URL。

<a href="{{ app.getRedirectUrl('my-custom-context') }}>Login</a>

现在在我们的模块或插件中,我们只需为AuthorizeController控制器注册一个事件处理器。

Event::on(AuthorizeController::class, AuthorizeController::EVENT_BEFORE_AUTHENTICATE, function (AuthorizationEvent $event) {
            if ($event->context === 'my-custom-context') {
                $event->returnUrl = 'https://google.com';
            }
});

成功了!现在登录后,用户将被发送到Google。

Venveo 提供