startsevdenis/oauth2-mosru

Mos.ru provider for league/oauth2-client

0.3.5 2022-06-21 07:43 UTC

This package is not auto-updated.

Last update: 2024-05-08 10:20:56 UTC


README

Latest Version License

Данный пакет предоставляет интеграцию Mos.ru для OAuth2 Client.

Установка

composer require knpuniversity/oauth2-client-bundle
composer require startsevdenis/oauth2-mosru

Использоваие

1. Настройка клиента

#knpu_oauth2_client.yaml

knpu_oauth2_client:
  clients:
    mosru:
      type: generic
      provider_class: StartsevDenis\OAuth2\Client\Provider\MosruProvider
      provider_options:
        environment: '%env(MOSRU_APP_ENV)%' #production or test
        scope: [ 'openid', 'profile', 'contacts', 'usr_grps' ] #необязательный параметр scope по умолчанию 'openid', 'profile', 'contacts'
      client_id: '%env(MOSRU_APP_ID)%'
      client_secret: '%env(MOSRU_APP_SECRET)%'
      redirect_route: mosru_check

2. Два роута в контроллере

# AuthConroller

use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

class AuthController extends AbstractController
{
...
    /**
     * Auth start
     *
     * @Route("/connect/mosru", name="connect_mosru_start")
     */
    public function connectAction(ClientRegistry $clientRegistry)
    {
        return $clientRegistry
            ->getClient('mosru')
            ->redirect();
    }
    
    /**
     * Auth end  
     * @Route("/auth/mosru/check", name="mosru_check")
     */
    public function mosruCheck()
    {
        #logic
    }
}

3. Авторизатор

В зависимости от версии symfony используем соответствующий авторизатор. Примеры авторизаторв на странице KnpUOAuth2ClientBundle

Пример авторизатора Symfony 5.4

#security.yaml

security:
  enable_authenticator_manager: true
  ...
  firewalls:
    ...
    main:
      ...
      custom_authenticators:
        - App\Security\MosRuAuthenticator

# App\Security\MosRuAuthenticator

namespace App\Security;

use Doctrine\ORM\EntityManagerInterface;
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
use KnpU\OAuth2ClientBundle\Security\Authenticator\OAuth2Authenticator;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;

class MosRuAuthenticator extends OAuth2Authenticator
{
    private $clientRegistry;
    private $entityManager;
    private $router;

    public function __construct(ClientRegistry $clientRegistry, EntityManagerInterface $entityManager, RouterInterface $router)
    {
        $this->clientRegistry = $clientRegistry;
        $this->entityManager = $entityManager;
        $this->router = $router;
    }

    public function supports(Request $request): ?bool
    {
        return $request->attributes->get('_route') === 'mosru_check';
    }

    public function authenticate(Request $request): Passport
    {
        $client = $this->clientRegistry->getClient('mosru');
        $accessToken = $this->fetchAccessToken($client);
        return new SelfValidatingPassport(
            new UserBadge($accessToken->getToken(), function() use ($accessToken, $client) {
                /* @var \StartsevDenis\OAuth2\Client\Provider\MosruResourceOwner */
                $owner = $client->fetchUserFromToken($accessToken);

                #getUser logic

                return $user;
            })
        );
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
    {
        //return url logic

        $targetUrl = $this->router->generate('index_page');

        return new RedirectResponse($targetUrl);

        // or, on success, let the request continue to be handled by the controller
        //return null;
    }

    public function onAuthenticationFailure(Request $request, AuthenticationException $exception): ?Response
    {
        $message = strtr($exception->getMessageKey(), $exception->getMessageData());

        return new Response($message, Response::HTTP_FORBIDDEN);
    }
}