How To Create a Custom Auth Driver in Laravel 4

I recently worked on a project where we needed to authenticate users using a SOAP webservice. (Yes, SOAP). Since we were building the app with Laravel we decided to create a custom authentication driver. By creating a custom driver you get to use all the functions you are used to, like Auth::attempt(), Auth::user(), Auth::check() etc. It's really easy to get started.

Let's start by creating a folder structure to store our files. You can store the provider where you want, but I recommend setting up a logical structure like this.


Then we add the project folder to the composer.json classmap so that our files get autoloaded. Remember to run a composer dumpautoload after.

"autoload": {
    "classmap": [

Next we have to create our class. Every authentication driver has to implement a UserProviderInterface. The interface requires that our class implements these functions:

public function retrieveById($identifier);
public function retrieveByCredentials(array $credentials);
public function validateCredentials(UserInterface $user, array $credentials);

First we create our namespace and define the classes we need from Laravel.

<?php namespace Project\Providers;

use Illuminate\Auth\UserProviderInterface;
use Illuminate\Auth\GenericUser;

Then we start creating our class. Remember we have to implement the UserProviderInterface.

class AuthUserProvider implements UserProviderInterface {

In this example we will be authenticating our user from an external webservice, so we create a private variable for it.

  * External webservice for authentication
  private $webservice;

We also create a user variable where we will store the user object.

  * The user object.
  private $user;

Next we set up our constructor that injects our webservice and defaults the user to null.

  * Constructor
  * @return void
  public function __construct(\Project\Webservice\Auth $webservice)
      $this->webservice = $webservice;
      $this->user = null;

Let's start by creating the first function. This function is exectuted when you do Auth::user() and returns the user object. We first check if the user is already fetched, so we only hit the webservice once per request. Note that this function requires that you return an id key.

  * Retrieves a user by id
  * @param int $identifier
  * @return mixed null|array
  public function retrieveByID($identifier)
      $this->user = is_null($this->user) ? $this->webservice->find($identifier) : $this->user;
      return $this->user;

Next we create the function that checks whether a user exists.

  * Tries to find a user based on the credentials passed.
  * @param array $crendtials username|password
  * @return mixed bool|UserInterface
  public function retrieveByCredentials(array $credentials)
      if(!$user = $this->webservice->find($credentials['username'])) return false;

      return new GenericUser($user);

Lastly we create the last function that checks if the user has passed the correct credentials and are cleared to be let in.

     * Validates the credentials passed to the ones in webservice.
     * @param UserInterface $user
     * @param array $credentials
     * @return bool
    public function validateCredentials(\Illuminate\Auth\UserInterface $user, array $credentials)
      return $this->webservice->validateCredentials($credentials['password'], $user->password);

Link to the full class

Now that we have created the class we have to tell Laravel we have a brand new authentication driver. A good place to put this is in app/start/global.php like so:

Auth::extend('customAuth', function($app) {
    $provider = new \Project\Providers\AuthUserProvider(new \Project\Webservice\Auth());
    return new \Illuminate\Auth\Guard($provider, $app['']);

The last thing we have to do in order to test our authentication driver is to enable it in app/config/auth.php.

'driver' => 'customAuth',

You are now the proud owner of your very own authentication driver. Please leave a comment if you have any feedback or questions.

comments powered by Disqus