Integrating OAuth on eZ sites using NetgenEzSocialConnectBundle

8 Dec 2016  | 
Filip Božanović
Integrating OAuth on eZ sites using NetgenEzSocialConnectBundle

In several recent projects we had been asked to implement ‘Login with Facebook’, ‘Login with Google’ functionality into eZ Publish 5 and eZ Platform, so we decided to go ahead and develop our own bundle based on HWIOAuthBundle.

While we kept ours in-house until very recently, Carlos Revillo open-sourced a bundle with much of the same functionality, but our needs were different enough to warrant continuing work on our own solution — the added flexibility of siteaccess-aware configuration were a must for our projects.

Rolling your own OAuth integration is fraught with pitfalls, so one of the requirements was to minimize the number of steps to get it working on a new project. Fortunately, HWIOAuthBundle does most of the heavy lifting for us, leaving us with the task of integrating it into eZ.

Typical workflow

For the sake of the argument, let’s suppose we’re using Facebook as our main social provider:

  1. The user clicks ‘Sign in with Facebook’.
  2. The user is directed to Facebook and is asked to authorize the site for logging in.
  3. After permission is given, our application receives their user ID from Facebook, as well as basic information — real name, email, and the profile image.
  4. If a user with that email is not registered on our site, a User object is created and filled with the returned data. Then, we add a DB entry representing a relation between the User object and the remote resource provider.
  5. The user is now logged in with their eZ User via Facebook.

Additional features

This bundle supports Facebook, Google, Twitter and LinkedIn sign-ins out of the box. These four providers are by far the most common use-cases for our clients and this constraint makes the bundle easier to maintain. Of course, the bundle can be extended easily if needed.

In addition to the ‘Connect with X’ template, usually included on login pages, there is a template which provides ‘Link to X’ and ‘Unlink from X’ functionality for each configured social provider, which can be included in user profile pages.

All relevant configuration can be defined per siteaccess. This means that, if we have, for instance, two siteaccesses representing two brands — the ‘Login with Facebook’ button on the RentalBoats site will link the user to the RentalBoats Facebook application, and the same goes for LuxuryCruisers.

Installation

Now that we know what the bundle does, let’s go over the installation. There are quite a few steps to setting it up, but most are straightforward, and most configuration can be taken directly from the documentation:

  1. Install the bundle via Composer
  2. Register both HWIOAuth bundle and NetgenEzSocialConnect bundle in the kernel
  3. Update the Doctrine schema

YAML configuration:

  1. Import routes
  2. Configure resource-owner data — client IDs and secrets

There are two configuration use-cases for our main config.yml:

Configuration variant A: using the same IDs and secrets on all siteaccesses

We need to define the parameters for HWIOAuth in its configuration section. This data can be adapted from the HWIOAuth installation docs with little modification, but I’ve added it here anyway for completeness:

hwi_oauth:
   firewall_name: ezpublish_front
   resource_owners:
      facebook:
         type: facebook
         client_id: 12345678
         client_secret: "12345678"
         scope: "email"
         infos_url: "https://graph.facebook.com/me?fields=id,name,email,picture.type(large)"
         paths:
            profilepicture: picture.data.url
netgen_social_connect:
   system:
      default:
         user_content_type_identifier: user
         field_identifiers:
            first_name: 'first_name'
            last_name: 'last_name'
            profile_image: 'image'                              
         resource_owners:
            facebook:
               user_group: 11

Configuration variant B: siteaccess-specific IDs and secrets

Here’s a sample configuration utilizing the configResolver component:

hwi_oauth:
   firewall_name: ezpublish_front
   resource_owners:
      facebook:
         type: facebook
         client_id: _placeholder
         client_secret: _placeholder
         scope: "email"
         infos_url: "https://graph.facebook.com/me?fields=id,name,email,picture.type(large)"
         paths:
            profilepicture: picture.data.url

netgen_social_connect:
   resource_owners:
      facebook: { use_config_resolver: true }
      twitter: { use_config_resolver: true }
   system:
      default:
         user_content_type_identifier: user
         field_identifiers:
            first_name: 'first_name'
            last_name: 'last_name'
            profile_image: 'image'
                   
         resource_owners:
            facebook:
               id: 12345678
               secret: 12345678
               user_group: 11
            twitter:
               id: 234567890
               secret: 234567890
               user_group: 11

      administration_group:
         user_content_type_identifier: admin_user
         field_identifiers:
            first_name: ‘firstname’
            last_name: 'lastname'
            profile_image: 'profile_pic'                               
         resource_owners:
            facebook:
               id: 987654321
               secret: 987654321
               user_group: 12

In addition to ‘default’, we can add a siteaccess name or siteaccess group, allowing us to map new social users to different content types, updating different fields, and creating the users in different group locations (such as Employee, Customer).

Finally, the ‘field_identifiers’ node defines how we map user data to eZ User objects. To finish, we configure the firewall.

Including the Twig templates

Rendering the login buttons is as simple as:

 {% include 'NetgenEzSocialConnectBundle:social:social_buttons.html.twig' %}

Bear in mind that it quickly became apparent that there is little point in attempting a generic solution for the different providers, and this template contains some provider-specific logic in both the frontend and the backend. You can extract only the crucial bits in your own login button templates.

Rendering the link/unlink template is a simple include statement as well:

 {% include ‘NetgenEzSocialConnectBundle:social:connect_user.html.twig’ %}

By design, if a user was created via OAuth (so there was no pre-existing user with these credentials), the social provider it was created with cannot be ‘unlinked’.

Final word

A word of caution — this bundle was primarily battle-tested to work with Facebook, as this was the most requested feature. Furthermore, each social login provider has their own peculiarities in the way authentication and authorization are handled, such as application permissions on their end, so adding new login providers may not be as straightforward as adding a new ResourceOwner class and mapping their ID and secrets to the configuration.

I hope you will find this guide helpful in using NetgenEzSocialConnectBundle in your own eZ Publish 5 and eZ Platform projects. We encourage you to contribute to the project, and be sure to let us know about any issues you encounter.

Comments

blog comments powered by Disqus

Short backstory of our blog: Sharing our experience from various web projects based on eZ Publish / eZ Platform, Symfony, PHP, HTML5, MySQL, jQuery, CSS, etc. and focusing on solving the problems we encountered.

Subscribe to RSS feed

Tags