lampask/oauth

Nette 框架中的 OAuth 集成

维护者

详细信息

github.com/lampask/oauth

源代码

安装: 1

依赖者: 0

建议者: 0

安全性: 0

星标: 0

关注者: 0

分支: 1

类型:项目

dev-main 2024-07-18 13:08 UTC

This package is auto-updated.

Last update: 2024-09-18 13:35:10 UTC


README

OAuth

👤 OAuth 集成到 Nette 框架

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

# ...

实现认证器

认证器是一个实现了 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 展示器

使用 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