$ composer require 68publishers/oauth
$ 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
$ 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
Sometimes it may be desirable to provide the configuration for an OAuth client dynamically if, for example, we have settings stored in a database. We can do this with the following implementation:
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 is a class implementing the AuthenticatorInterface
interface.
This class should return the identity of the user and throw an AuthenticationException
exception in case of any problem.
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(/* ... */);
}
}
The OAuthPresenterTrait
trait is used for simple implementation.
Next, you need to define three methods that determine what should happen if the authentication is successful or fails.
All three methods should redirect at the end.
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:');
}
}
The login button can be rendered simply as follows
<a n:href="OAuth:authorize, type => 'azure'">Login via Azure</a>
If you store the request (back link) using Presenter::storeRequest()
you can also pass it the URL.
Your OAuthPresenter
will then automatically redirect to this link after successful authentication.
<a n:href="OAuth:authorize, type => 'azure', backLink => $backLink">Login via Azure</a>
The package is distributed under the MIT License. See LICENSE for more information.