2017 © Pedro Peláez
 

symfony-bundle connect-bundle

Official bundle for the SensioLabs Connect SDK

image

sensiolabs/connect-bundle

Official bundle for the SensioLabs Connect SDK

  • Wednesday, January 17, 2018
  • by fabpot
  • Repository
  • 18 Watchers
  • 25 Stars
  • 15,165 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 12 Forks
  • 0 Open issues
  • 23 Versions
  • 2 % Grown

The README.md

symfony/connect-bundle

About

This is the official bundle of the SymfonyConnect SDK., (*1)

Installation

Step 1: Install symfony/connect-bundle using Composer

$ composer require symfonycorp/connect-bundle

If you're not using Symfony Flex, please take inspiration from this bundle's recipe to enable it., (*2)

Step 2: Configure your .env.local file

SYMFONY_CONNECT_APP_ID='Your app id'
SYMFONY_CONNECT_APP_SECRET='Your app secret'

Usage

Use SymfonyConnect to authenticate your user

Step 1: Configure the security

Note: If you want to persist your users, read the Cookbooks section., (*3)

If you don't want to persist your users, you can use ConnectInMemoryUserProvider:, (*4)

# config/packages/security.yaml
security:
    providers:
        symfony_connect:
            connect_memory: ~
    firewalls:
        # [...]

        secured_area:
            pattern: ^/
            symfony_connect:
                check_path: symfony_connect_callback
                login_path: symfony_connect_login
                failure_path: home # need to be adapted to your config, see step 4
                remember_me: false
                provider: symfony_connect
            anonymous: true

You can also load specific roles for some users:, (*5)

# config/packages/security.yaml
security:
    providers:
        symfony_connect:
            connect_memory:
                users:
                    90f28e69-9ce9-4a42-8b0e-e8c7fcc27713: "ROLE_CONNECT_USER ROLE_ADMIN"

Note: The username is the user uuid., (*6)

You can generate a link to the SymfonyConnect login page:, (*7)

<a href="{{ url('symfony_connect_login') }}">Connect</a>

You can also specify the target URL after connection:, (*8)

<a href="{{ url('symfony_connect_login') }}?target=XXX">Connect</a>

Step 3: Play with the user

The API user is available through the token storage, which you can get by autowiring Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface $tokenStorage., (*9)

$user = $tokenStorage->getToken()->getApiUser();

If you use the built-in security component, you can access to the root api directly by autowiring SymfonyCorp\Connect\Api\Api $api:, (*10)

$user = $api->getRoot()->getCurrentUser();

You can also get access to the API root object by providing an access token explicitly:, (*11)

$accessToken = $tokenStorage->getToken()->getAccessToken();
$api->setAccessToken($accessToken);
$root = $api->getRoot();
$user = $root->getCurrentUser();

Step 4: Handling Failures

Several errors can occur during the OAuth dance, for example the user can deny your application or the scope you defined in symfony_connect.yaml can be different from what you selected while creating your application on SymfonyConnect. Theses failures arehandled by the default Symfony failure handling., (*12)

Therefore, if an error occurred, the error is stored in the session (with a fallback on query attributes) and the user is redirected to the route/path specificed in failure_path node of the symfony_connect section of your firewall in security.yaml., (*13)

Warning: You need to specifiy failure_path. If you don't, the user will be redirected back to login_path, meaning that will launch the SymfonyConnect authentication and redirect the user to SymfonyConnect which can lead to a redirection loop., (*14)

This means you need to fetch the authentication error if there is one and display it in the view. This is similar to what you do for a typical login form on Symfony (here we assume you have a home route pointing to the following controller):, (*15)

// src/Controller/HomeController.php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;

class HomeController extends AbstractController
{
    /**
     * @Route("/", name="home")
     */
    public function home(Request $request)
    {
        $session = $request->hasSession() ? $request->getSession() : null;

        // get the authentication error if there is one
        if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
            $error = $request->attributes->get(Security::AUTHENTICATION_ERROR);
        } elseif (null !== $session && $session->has(Security::AUTHENTICATION_ERROR)) {
            $error = $session->get(Security::AUTHENTICATION_ERROR);
            $session->remove(Security::AUTHENTICATION_ERROR);
        } else {
            $error = '';
        }

        return $this->render('home.html.twig', ['error' => $error]);
    }
}

And then adapt your twig template:, (*16)

{# templates/home.html.twig #}

{% if app.user %}
    Congrats! You are authenticated with SymfonyConnect
{% elseif error %}
    {{ error.messageKey | trans(error.messageData, 'security') }}
{% else %}
    <a href="{{ url('symfony_connect_login') }}">Log in with SymfonyConnect</a>
{% endif %}

Cookbooks

How to persist users

Step 1 - Create a User entity

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use SymfonyCorp\Connect\Api\Entity\User as ConnectApiUser;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 */
class User implements UserInterface
{
    /** @ORM\Column(type="integer") @ORM\Id @ORM\GeneratedValue(strategy="AUTO") */
    private $id;

    /** @ORM\Column(type="string", length=255) */
    private $uuid;

    /** @ORM\Column(type="string", length=255) */
    private $username;

    /** @ORM\Column(type="string", length=255) */
    private $name;

    public function __construct($uuid)
    {
        $this->uuid = $uuid;
    }

    public function updateFromConnect(ConnectApiUser $apiUser)
    {
        $this->username = $apiUser->getUsername();
        $this->name = $apiUser->getName();
    }

    public function getUuid()
    {
        return $this->uuid;
    }

    public function getUsername()
    {
        return $this->username;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getRoles()
    {
        return ['ROLE_USER'];
    }

    public function getPassword()
    {
    }

    public function getSalt()
    {
    }

    public function eraseCredentials()
    {
    }
}

Step 2 - Create the repository

<?php

namespace App\Repository;

use App\Entity\User;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;

class UserRepository extends ServiceEntityRepository implements UserProviderInterface
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, User::class);
    }

    public function loadUserByUsername($uuid)
    {
        return $this->findOneByUuid($uuid) ?: new User($uuid);
    }

    public function refreshUser(UserInterface $user)
    {
        if (!$user instanceof User) {
            throw new UnsupportedUserException(sprintf('class %s is not supported', get_class($user)));
        }

        return $this->loadUserByUsername($user->getUuid());
    }

    public function supportsClass($class)
    {
        return User::class === $class;
    }
}

Don't forget to update your database., (*17)

Step 3 - Create the event listener

<?php

namespace App\EventListener;

use Doctrine\ORM\EntityManagerInterface;
use SymfonyCorp\Connect\Security\Authentication\Token\ConnectToken;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;

class SecurityInteractiveLoginListener implements EventSubscriberInterface
{
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    public function registerUser(InteractiveLoginEvent $event)
    {
        $token = $event->getAuthenticationToken();

        if (!$token instanceof ConnectToken) {
            return;
        }

        $user = $token->getUser();
        $user->updateFromConnect($token->getApiUser());

        $this->em->persist($user);
        $this->em->flush($user);
    }

    public static function getSubscribedEvents()
    {
        return [
            SecurityEvents::INTERACTIVE_LOGIN => 'registerUser',
        ];
    }
}

Step 4 - Configure security

# config/packages/security.yaml
security:
    encoders:
        App\Entity\User: plaintext

    providers:
        symfony_connect:
            id: App\Repository\UserRepository

Step 5 - Enjoy

You can store more things if you want. But don't forget to update your application scope., (*18)

License

This bundle is licensed under the MIT license., (*19)

The Versions

17/01 2018

dev-master

9999999-dev https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

17/01 2018

v4.3.10

4.3.10.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

13/10 2017

v4.3.9

4.3.9.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

13/10 2017

dev-symfony4-data-collector-fix

dev-symfony4-data-collector-fix https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

29/09 2017

dev-symfony4-compat

dev-symfony4-compat https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

29/09 2017

v4.3.8

4.3.8.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

29/09 2017

v4.3.7

4.3.7.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

28/09 2017

v4.3.6

4.3.6.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

29/08 2017

v4.3.5

4.3.5.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

06/01 2017

v4.3.4

4.3.4.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

03/01 2017

v4.3.3

4.3.3.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

03/01 2017

v4.3.2

4.3.2.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

03/01 2017

v4.3.1

4.3.1.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

03/01 2017

v4.3.0

4.3.0.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

28/12 2015

v4.2.2

4.2.2.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

12/12 2014

v4.2.1

4.2.1.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

12/12 2014

v4.2.0

4.2.0.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

21/10 2014

v4.1.0

4.1.0.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

12/09 2014

v4.0.0

4.0.0.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

24/07 2014

v3.1.0

3.1.0.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

18/07 2014

v3.0.0

3.0.0.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

26/12 2013

v2.0.0

2.0.0.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect

15/02 2013

v1.0.0

1.0.0.0 https://github.com/sensiolabs/SensioConnectBundle

Official bundle for the SensioLabs Connect SDK

  Sources   Download

MIT

The Requires

 

by SensioLabs

sensiolabs connect