Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 5.1 multiple authentication

How can you authenticate multiple types of users in Laravel 5.1 e.g. Jobseeker, Recruiter, Admin etc.

Some of you have suggested using a single users table to store only the password and email, creating profile tables to store user specific information (jobseeker_profile, recruiter_profile) and using roles to differentiate between the different types of users (i.e having a roles and role_user) table.

This is all very well but then what if the different types of users have different registration and login forms. How do you customize the default auth controller out of the box to display the correct view?

So if I have the following routes:

// Jobseeker Authentication routes...
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@postLogin');
Route::get('auth/logout', 'Auth\AuthController@getLogout');

// Jobseeker Registration routes...
Route::get('auth/register', 'Auth\AuthController@getRegister');
Route::post('auth/register', 'Auth\AuthController@postRegister');


// Recruiter Authentication routes...
Route::get('recruiter/auth/login', 'Auth\AuthController@getLogin');
Route::post('recruiter/auth/login', 'Auth\AuthController@postLogin');
Route::get('recruiter/auth/logout', 'Auth\AuthController@getLogout');

// Recruiter Registration routes...
Route::get('recruiter/auth/register', 'Auth\AuthController@getRegister');
Route::post('recruiter/auth/register', 'Auth\AuthController@postRegister');

This is the default auth controller out of the box:

class AuthController extends Controller
{
    use AuthenticatesAndRegistersUsers;

    public function __construct()
    {
        $this->middleware('guest', ['except' => 'getLogout']);
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|confirmed|min:6',
        ]);
    }

    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }
}    

traits used by the default out of the box auth controller:

trait AuthenticatesUsers
{
   use RedirectsUsers;

   public function getLogin()
   {
        return view('auth.login');
    }

   public function postLogin(Request $request)
   {
        $this->validate($request, [
            'email' => 'required|email', 'password' => 'required',
        ]);

        $credentials = $this->getCredentials($request);

        if (Auth::attempt($credentials, $request->has('remember'))) {
            return redirect()->intended($this->redirectPath());
        }

        return redirect($this->loginPath())
            ->withInput($request->only('email', 'remember'))
            ->withErrors([
               'email' => $this->getFailedLoginMessage(),
            ]);
   }

    public function loginPath()
   {
        return property_exists($this, 'loginPath') ? $this->loginPath : '/auth/login';
    }

}

trait RegistersUsers
{
    use RedirectsUsers;

    public function getRegister()
    {
        return view('auth.register');
    }

    public function postRegister(Request $request)
    {
        $validator = $this->validator($request->all());

        if ($validator->fails()) {
            $this->throwValidationException(
                $request, $validator
            );
         }

         Auth::login($this->create($request->all()));

        return redirect($this->redirectPath());
    }
}

I'm sure this is a very common requirement for many web applications but I can't find any helpful tutorials for Laravel specific implementations. All the tutorial simply focus on the out of the box implementation for some odd reason.

Any help on the above would be much appreciated.

like image 554
adam78 Avatar asked Aug 30 '15 08:08

adam78


2 Answers

This is not a solution to your question directly, but alternative way to solve your question problem with.

In stead of creating different username and password for different groups, make a central authentication that has roles. It called user and roles.

You can define groups with different roles, and each roles has specific access to respective area.

Regarding registration process you can make two differnet views but using the same controller, and for each view you can create a hidden field to indicate if it is jobseekers group or recruiter group.

Both will receive two different confirmation emails where they should fill the rest of the profile information, like recruiter should put company name and jobseeker should put his name etc. they might have two different tables for profile information, but still using the same login system.

By adding condition to middleware and correct route, if jobseeker tries to access recruiter area even if jobseeker is logged in the system, the jobseeker won't be able to access that area or the opposite way.

Since Laravel 5.1 has build in user login system, so you have few choices, build your own roles or use 3rd party.

I suggest you to build your own so you have control over your code and can further develop it as you wish with time. It might take you half day to get it run and understand how it works, but it is worth spending that time with the right approach in stead of the way you go in your Question OR using 3rd party is fine too, there is a lot of packages around you can search for. I have personally used Entrust (https://github.com/Zizaco/entrust) it is easy and nice way to provide roles and permissions to your project.

Here is also a link to video developed by Jeffrey Way at Laracast, it builds user and roles system from scratch for Laravel 4. but since you have user part, just follow roles part and with small modifications you will have a roles system to your Laravel 5.1, I have tried it and it works.

Regarding your question in the comments, when you follow the video you will understand the concept.

Link to the video: https://laracasts.com/lessons/users-and-roles

You might need to create account to see the video, most of videos are free.

Good practice It is always also a good practice to illustrate what you want to achieve that makes things easier, I have just made an example for your project, but that is only example for learning:

enter image description here

I encourage you to read some of the topics regarding roles, here you will also find some inspiration to 3rd party acl systems to Laravel, there might be more articles but here is some:

Reading:
https://laracasts.com/discuss/channels/laravel/which-package-is-best-for-roles-permissions/?page=2
https://laracasts.com/discuss/channels/general-discussion/laravel-5-user-groups-management
https://laracasts.com/discuss/channels/general-discussion/roles-and-permissions-in-laravel-5


EDIT

Important Note
Laravel 5.1 has introduced Authorization, I have not found much documentation online yet but it is worth to spend some time learning it:

http://laravel.com/docs/5.1/authorization#policies

NEW UPDATE
There are some great videos solution for what you asking, follow ACL parts here https://laracasts.com/series/whats-new-in-laravel-5-1

This might be very interesting too: https://laracasts.com/lessons/email-verification-in-laravel

This will give you a complete own developed solution.

like image 65
Maytham Avatar answered Oct 19 '22 18:10

Maytham


You can achieve multiple authentication easily by pulling up the sarav/laravel-multiauth package

 composer require sarav/laravel-multiauth

I assume you have separate tables for Jobseeker, Recruiter, Admin.

Step 1 : Open app.php and replace

Illuminate\Auth\AuthServiceProvider::class

with

Sarav\Multiauth\MultiauthServiceProvider::class

Then, open up auth.php file and remove

<?php

return [

    'driver' => 'eloquent',
    'model'  => 'App\User::class',
    'table'  => 'users',
    'password' => [
       'email' => 'emails.password',
       'table' => 'password_resets',
       'expire' => 60,
    ],
];

and add the following code

return [
'multi' => [
    'jobseeker' => [
        'driver' => 'eloquent',
        'model'  => App\Jobseeker::class, // Model Class
        'table'  => 'jobseeker' // jobseeker table
    ],
    'recruiter' => [
        'driver' => 'eloquent',
        'model'  => App\Recruiter::class, // Model Class
        'table'  => 'recruiter' //recruiter table
    ],
    'admin' => [
        'driver' => 'eloquent',
        'model'  => App\Admin::class, // Model Class
        'table'  => 'admin' //admin table
    ],
 ],
 'password' => [
       'email' => 'emails.password',
       'table' => 'password_resets',
       'expire' => 60,
  ]
 ];

Thats it!

Now you can try login attempt by calling

\Auth::attempt('jobseeker', ['email'=> '[email protected]', 'password' => 'secret']);

\Auth::attempt('recruiter', ['email'=> '[email protected]', 'password' => 'secret']);

\Auth::attempt('admin', ['email'=> '[email protected]', 'password' => 'secret']);

Always remember first paramter should be your user parameter. Here I have given jobseeker for jobseeker login attempt, recruiter for recruiter attempt and admin for admin login attempt. Without the proper first parameter system will throw exception.

For more detailed information checkout this article http://sarav.co/blog/multiple-authentication-in-laravel-continued/

like image 2
Saravanan Sampathkumar Avatar answered Oct 19 '22 18:10

Saravanan Sampathkumar