Nette 框架中的 OAuth 集成

安装: 127

依赖: 0

建议者: 0

安全性: 0

星标: 1

关注者: 2

分支: 1

开放问题: 0

类型:项目

v1.0.0 2024-01-29 01:14 UTC

This package is auto-updated.

Last update: 2024-08-29 02:26:43 UTC


README

OAuth

👤 Nette 框架中的 OAuth 集成

Checks Coverage Status Total Downloads Latest Version PHP Version

安装

$ composer require 68publishers/oauth

配置

Facebook

$ composer require league/oauth2-facebook
extensions:
    68publishers.oauth: SixtyEightPublishers\OAuth\Bridge\Nette\DI\OAuthExtension
    68publishers.facebook: SixtyEightPublishers\OAuth\Bridge\Nette\DI\FacebookOAuthExtension

68publishers.facebook:
    flowName: facebook # default, not necessary to define
    config:
        enabled: true # default, not necessary to define
        clientId: '<client id>'
        clientSecret: '<client id>'
        graphApiVersion: '<graph api version>'
        options: [] # additional options that are passed into the client
    authenticator: App\OAuth\FacebookAuthenticator

Azure

$ composer require thenetworg/oauth2-azure
extensions:
    68publishers.oauth: SixtyEightPublishers\OAuth\Bridge\Nette\DI\OAuthExtension
    68publishers.azure: SixtyEightPublishers\OAuth\Bridge\Nette\DI\FacebookOAuthExtension

68publishers.azure:
    flowName: azure # default, not necessary to define
    config:
        enabled: true # default, not necessary to define
        clientId: '<client id>'
        clientSecret: '<client id>'
        tenantId: '<tenant id>' # optional, use this option only if your Azure Entra ID application is configured as a single tenant.
        options: [] # additional options that are passed into the client
    authenticator: App\OAuth\AzureAuthenticator

集成

懒配置

有时可能需要动态地提供 OAuth 客户端的配置,例如,如果我们在数据库中存储了设置。我们可以通过以下实现来完成这项工作:

namespace App\OAuth\Config;

use SixtyEightPublishers\OAuth\Config\Config;
use SixtyEightPublishers\OAuth\Config\LazyConfig;
use App\SettingsProvider;

final class AzureConfig extends LazyConfig
{
    public function __construct(SettingsProvider $provider) {
        parent::__construct(
            configFactory: static function (): Config {
                return new Config(
                    flowEnabled: $provider->get('azure.enabled'),
                    options: [
                        'clientId' => $provider->get('azure.clientId'),
                        'clientSecret' => $provider->get('azure.clientSecret'),
                    ],
                );
            }
        );
    }
}
# ...

68publishers.azure:
    config: App\OAuth\Config\AzureConfig

# ...

实现 Authenticator

Authenticator 是一个实现了 AuthenticatorInterface 接口的类。这个类应该返回用户的身份,并在出现任何问题时抛出 AuthenticationException 异常。

namespace App\OAuth;

use SixtyEightPublishers\OAuth\Authentication\AuthenticatorInterface;
use SixtyEightPublishers\OAuth\Exception\AuthenticationException;
use SixtyEightPublishers\OAuth\Authorization\AuthorizationResult;
use Nette\Security\IIdentity;
use Nette\Security\SimpleIdentity;

final class AzureAuthenticator implements AuthenticatorInterface
{
    public function authenticate(string $flowName, AuthorizationResult $authorizationResult): IIdentity
    {
        $accessToken = $authorizationResult->accessToken;
        $resourceOwner = $authorizationResult->resourceOwner;
        
        if ($userCannotBeAuthenticated) {
            throw new AuthenticationException('User can not be authenticated.');
        }
        
        return new SimpleIdentity(/* ... */);
    }
}

实现 OAuth Presenter

使用 OAuthPresenterTrait 特性进行简单实现。接下来,你需要定义三个方法,这些方法决定了如果认证成功或失败时应该发生什么。所有三个方法都应该在最后进行重定向。

namespace App\Presenter;

use Nette\Application\UI\Presenter;
use SixtyEightPublishers\OAuth\Bridge\Nette\Application\OAuthPresenterTrait;
use SixtyEightPublishers\OAuth\Exception\OAuthExceptionInterface;

final class OAuthPresenter extends Presenter
{
    use OAuthPresenterTrait;
 
    protected function onAuthorizationRedirectFailed(string $flowName, OAuthExceptionInterface $error): void
    {
        $this->flashMessage('Authentication failed', 'error');
        $this->redirect('SignIn:');
    }

    abstract protected function onAuthenticationFailed(string $flowName, OAuthExceptionInterface $error): void
    {
        $this->flashMessage('Authentication failed', 'error');
        $this->redirect('SignIn:');
    }

    abstract protected function onUserAuthenticated(string $flowName): void
    {
        $this->flashMessage('You have been successfully logged in', 'success');
        $this->redirect('Homepage:');
    }
}

登录按钮

登录按钮可以简单地按照以下方式渲染

<a n:href="OAuth:authorize, type => 'azure'">Login via Azure</a>

如果你使用 Presenter::storeRequest() 存储请求(回链),你也可以传递 URL。然后,你的 OAuthPresenter 将在成功认证后自动重定向到该链接。

<a n:href="OAuth:authorize, type => 'azure', backLink => $backLink">Login via Azure</a>

许可证

该软件包在 MIT 许可证下分发。有关更多信息,请参阅 LICENSE