Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 4 Multi User Authentication

I'm building a Laravel 4 app that requires login authentication for 3 entity types: Coach, Student & Admin, all with separate user interfaces. While I could use a package like Sentry 2 and a single DB user table with user types to achieve this, something about the potential polymorphic DB design patterns and headaches that can occur down the track, don't sit well with me. Having dealt with polymorphic issues in the past with previous apps, and the grief it can create when you want to normalise your DB structure, etc. having separate DB tables for each entity type seems a better way to go.

How would you solve this design problem?

Laravel 4 auth uses basically the following files:

  • Auth.php (facade)
  • AuthManager.php
  • AuthServiceProvider.php
  • Guard.php
  • auth.php (config)
  • User.php (eloquent model)

I've played around with duplicating these files to come up with mostly an independent auth for the coach entity that works, registering the facade and service provider in the app.php file, as well as making the necessary changes to config to use the Coach eloquent model for authentication:

  • AuthCoach.php (facade)
  • AuthCoachManager.php
  • AuthCoachServiceProvider.php
  • Guard.php
  • authcoach.php (config)
  • Coach.php (eloquent model)

I am still using Guard.php from the standard Laravel 4 auth, but Guard can easily be extended if the need arises to customise Guard methods for coach authentication by creating a GuardCoach.php file.

If I'm going to have separate auth for each entity type, do you think this is a good way to achieve it?

Can you see any potential problems or know a better way of doing this?

like image 357
Ben Avatar asked Sep 07 '13 10:09

Ben


2 Answers

Maybe I do not understand your context well, but why dont you just use the basic concept of role based access control and render different stuff for different roles ? If that is not tight enough you can use attribute based auth policies to granulate permissions. What are the reasons you want to duplicate (triple that is) auth-logic? Not mentioning the fact of redundant db data (separate user table for separate user type? yuk!) ?

If you are not satisifed with Sentry (personally, I dont use that library) I can recommend Zizaco/Confide + Zizaco/Entrust as a clean and elegant solution for user/role/permission management. Check it out here Zizaco GitHub.

A quick general idea:

  • use a single clean authentication mechanism for whole app
  • granulate access with Roles or Roles+Permissions
  • separate your admin logic into separate controllers (AdminUserController, AdminCoachController, whatever..)
  • I see no difficulties in composing appropriate blade templating structure to have it all nicely done and well organised

What are your polymorphic concerns?

If you are worrying that your user table will get cluttered, leave it be as a place to store auth details and put all other necessary (non-auth) user details in another table.

Hope this helps you out, if only I understood your problem well.

like image 157
Gadoma Avatar answered Sep 23 '22 22:09

Gadoma


I think you are trying to swat a mosquito using a mallet.

Here is how I tackled the same problem:

  • I wanted to make sure that each user's authentication (username, password) is stored in the same table. Basically, I had three types of users.

  • I used Sentry 2 which makes it a breeze to manage the authentication stuff.

  • Using the default migrations provided by Sentry 2, I added a column 'role' to the 'users' table - which differentiates the 3 types of users.

  • For each user type, I created a table with specific fields.

  • When the user authenticated, I would grab their 'role' from the 'users' table, run a few if statements and know which view to serve them.

And the mosquito was completely dead.

Onto yours:

  • Basically, both our approaches are the same - since each user type has a separate table for fields they don't all share (except first name, last name, email, password, last login etc).

  • Your approach will allow a user to belong to the three entities - which is logically not correct. Mine won't - which is logically...

  • You are afraid of 'polymorphic issues' but I don't think we have a lot to deal with here. All we would perhaps do is define in our models that a coach, for example, belongsTo a user. And a user hasOne coach.

  • But in reality, we don't even need to define the relationships. Because at authentication, we need to run if statements anyway. So, using the user object returned from authentication, we will know two things: which table to then go to for user-type-sepecific information and which view to serve to the authenticated user.

Don't be afraid, son

like image 38
kJamesy Avatar answered Sep 23 '22 22:09

kJamesy