Propel and FOSUserBundle authentication in Symfony2

June 18, 2021

Tags: IT Staff EN 2024
Share

Table of contents

Quick Access

software development

 

In this guide, I’ll explain how to manage users in Symfony2, introduce its basic security features, and demonstrate how to implement an efficient user management system in under 15 minutes. Throughout, I’ll provide tips to help you stay focused on your application rather than spending time searching the internet. This tutorial assumes a basic knowledge of PHP and that you have a basic installation of Symfony2 for testing the code provided.

 

software development

 

Introduction to Symfony2’s Security System

User management is one of the most sensitive parts of web application development, especially when it comes to security. Although Symfony2 offers a robust and comprehensive security system, it lacks built-in tools like a login form or user management actions by default. Symfony2 often uses Propel, an ORM for PHP5, to handle databases. Propel allows you to manipulate databases with a set of objects and is widely used in Symfony2 projects.

 

Fortunately, the Friends Of Symfony community has developed FOSUserBundle. This bundle integrates seamlessly with Symfony2’s security component, offering a simple yet powerful solution for user management. FOSUserBundle works well with Propel and provides a default User.php management class for handling users.

 

Configuring FOSUserBundle

  1. Configuring Security in config.yml

    Add the following lines to your config.yml:

    providers:    fos_userbundle:        id: fos_user.user_provider.username firewalls:    main:        pattern: ^/        form_login:            provider: fos_userbundle            csrf_provider: security.csrf.token_manager        logout: true        anonymous: true access_control:    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }    - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }    - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }

    In this setup, we define a new security provider, instructing Symfony to use fos_user.user_provider.username to validate and reload users from the database. Additionally, we specify open access to login, register, and resetting routes without authentication.

     

  2. Setting FOSUserBundle to Use Propel

    Next, configure FOSUserBundle in security.yml:

     
    fos_user:    db_driver: propel    firewall_name: main    user_class: FOS\UserBundle\Propel\User
  3. Adding Routes in routing.yml

    Finally, load the FOSUserBundle routes in routing.yml:

     
    fos_user:    resource: "@FOSUserBundle/Resources/config/routing/all.xml"

    This configuration provides all the necessary routes, but you can define specific routes if needed.

     

Extending the User Class in FOSUserBundle

If you need to add new features or methods, you can extend the default user class by creating a custom user class and updating the configuration in config.yml:

 
fos_user:    db_driver: propel    firewall_name: main    user_class: Acme\MyBundle\Model\User

However, you may encounter issues since the authentication process will continue to use the original FOS\UserBundle user class, causing errors such as failed logins. To address this, we need to create a custom user provider.

 

Creating a Custom User Provider

  1. Define a Custom User Provider

    Create a new user provider class in Acme\MyBundle\Security\UserProvider:

     
    // Acme\MyBundle\Security\UserProvider class UserProvider extends FOS\UserBundle\Security\UserProvider {    protected $userManager;    public function __construct(UserManagerInterface $userManager)    {        $this->userManager = $userManager;        parent::__construct($userManager);    }    public function refreshUser(UserInterface $user)    {        if (!$user instanceof User && !$this->supportsClass(get_class($user))) {            throw new UnsupportedUserException(sprintf('Expected an instance of FOS\UserBundle\Model\User, but got "%s".', get_class($user)));        }        if (null === $reloadedUser = $this->userManager->findUserBy(['id' => $user->getId()])) {            throw new UsernameNotFoundException(sprintf('User with ID "%d" could not be reloaded.', $user->getId()));        }        return $reloadedUser;    } }
  2. Register the Custom User Provider as a Service

    In services.yml, register the custom user provider:

     
    // Acme\MyBundle\Resources\config\services.yml services:    my.user.provider:        class: Acme\MyBundle\Security\UserProvider        arguments: [@fos_user.user_manager.default]
  3. Update Security Configuration

    Update security.yml to use the custom user provider:

     
    providers:    fos_userbundle:        id: my.user.provider

 

Resolving Class Mapping Issues

To ensure correct mapping of your extended user class, use GlorpenPropelBundle, which allows Propel to extend functionality through additional events and behaviors.

  1. Install GlorpenPropelBundle

    Run the following command to install the bundle:

    composer require glorpen/propel-bundle
  2. Configure GlorpenPropelBundle in config.yml

    Add the following to the Propel configuration in config.yml:

    build_properties:    propel.behavior.extend.class: 'vendor.glorpen.propel-bundle.Glorpen.Propel.PropelBundle.Behaviors.ExtendBehavior'    propel.behavior.default: "extend"
  3. Define Extended Models

    In the glorpen_propel section of config.yml, add:

    glorpen_propel:    extended_models:        FOS\UserBundle\Propel\User: Acme\MyBundle\Model\User

 

With these steps completed, your custom user class will work smoothly with FOSUserBundle, preventing potential errors in the authentication process. FOSUserBundle, almost an extension of Symfony2 itself, is incredibly quick and simple to implement with Propel. It allows you to focus on your application logic without worrying about authentication and user management.

 

I hope this mini-tutorial has been helpful. Next, I’ll write about handling sessions with JWT and FOSUserBundle in Symfony2.

 

We recommend you this video