Creating admin guard VS using the default guard for both users and admins - laravel

Since I had problem with Passport multi auth, I wonder is it necessary to have an admin guard (and an admins table) or it's better to use the default guard (and users table) for both admins and users with the help of role and permissions? Which is better?

That's a really hard question to answer without more information, but I'll try looking at it from a few perspectives:
You have an application that has users that can turn into admins (and vice-versa)
In this situation, I would probably have a single table that contains an is_admin column and use the column to validate whether the user can perform administration tasks (e.g. by using Laravel's gates). The downside to this is that if you wanted to create a third type of user (e.g. supervisor), you would need to change the model used.
You have an application where users are completely separate from administrators
If you control the administrators and everyone else is just a user, creating separate guards could be used, this does allow for a lot of flexibility in the future if you wanted to implement different authentication flows for both administrators and users (for example, using SAML). If you were to add a third type of user (e.g. supervisor), you could then just create another guard.
You have an application that can have different (customisable) permissions for each user
In this case I would recommend implementing a roles table, a permissions table, a role_permissions table and adding a column called role_id to the user table. This provides the most flexibility and is also usable with the Laravel's gate system, but is probably the most difficult to setup and hardest to maintain.
For the application I develop, we use a mixture of roles and guards. We use roles for users as each user gets a customisable set of permissions. We then use a separate guard for API users which inherit the permissions of the user they were authenticated with.

Related

Can we use laravel-permissions for multi tenant application?

I am creating one multi-tenant app in Laravel with Single Database and thinking to use laravel-permission package by spatie.
My Requirement is pretty straightforward, I want my tenants to create their own Roles, whereas permissions will be managed by Super Admin only.
My problem is when I was trying using, It worked for 1st client but 2nd time it gives error:
A role 'Admin' already exists for guard 'admin'.
As I mentioned client can create roles, so they can crate duplicate roles.
Please recommend better approach or package or should I try writing custom code.
Any help appreciated!
Because the name is indexed in the role table, you cannot create a duplicate role name, I ask you not to change the package, but in case you have 2 ways to handle this
1- unindex the name collemn or disable unique feature, and add you tenant id to table so by do this you can manage and get right role for each tenant
2- add another table to manage your sub role (tenant role) and connect you sub role with master role by id
I would consider using a hidden prefix: on the roles and permissions that would scope them to a particular tenant. So for example:
Roles
system:admin
tenant_a:admin
tenant_b:admin
Permissions
system:creates-roles
system:reads-roles
tenant_a:creates-roles
tenant_a:reads-roles
The prefix would not be assignable by a Tenant, the system would automatically assign that based on the User. However, if you're a System Admin (i.e. Super Admin) then you could create/view/assign a prefix in order to manage the roles and permissions.
This would require you to write some custom logic for handling the prefix, however, it is pretty flexible (you could nest unlimited identifiers - a:b:c:d:e etc.) and doesn't require you to go messing with any underlying packages (i.e. laravel-permissions).

Laravel Multi-auth (multiple user tables) from same login

I plan to develop a system that has three user types (admin, business, personal). I want to have each user types information stored in a separate table for easy access and to reduce the number of blank fields (if they were all in one table).
Having looked at multiple Multi-auth packages available for Laravel, they all appear to be insisting on an approach with URLs like the following:
/admin/login
/business/login
/personal/login
Ideally, I would like to take an approach where the standard Laravel Auth /login can be used meaning that all users log in from the same page.
My knowledge of Laravel is limited so all and any help is appreciated.
The usual approach is to have one users table which has the ID/email/username (as primary key), login credentials and user types for all the users which will be logging into the system. The information however can be stored in separate tables for each type, referencing the foreign key.
After authenticating the user, then you can decide what to do with the user based on the user type.
If you store login credentials in multiple tables, that's data redundancy. Unless you want the same email/username to have more than one user type, but then during login, the user has to decide which user type they want to log into (maybe by selecting a dropdown option).
Update: about user roles
If you need to simply redirect users after logging in, use $redirectTo. Or if you need to decide what to do with the users depending on the roles after logging, you can make use of authenticated() method (add this method if it's not already there, it will overwrite the AuthenticatesUsers trait) inside your AuthController/LoginController.
Throughout your application, I'd suggest assigning middleware to route groups to restrict routes based on user roles. And yes, in your views and controllers you can use something like if(Auth::user()->hasRole('business')) when needed, but first you'll need to create the hasRole() method in your User model. If you feel it's getting complicated, you may try packages like laravel-permission and Entrust. I haven't tried them though :)

Laravel: ACL and Roles for Users. Am I thinking this right?

I am about to define permissions for users in my project. I checked the laracasts videos regarding ACL, Roles and Permissions.
I have a doubt. Do I need Roles for normal users?
I mean, in my project a user should be able to create / update / delete his own posts, he should be able to comment on his own posts and posts by other users and delete his posts and posts left by others on his own posts.
The point is: do I really need to define Roles for this kind of permissions? Shouldn't I just define some policies like can / can't post / update / delete etc. and only define roles for admins?
You don't necessarily need a full featured, powerful Roles/ACL system but if you are storing both admin and basic users in the same table then you do need something to distinguish between them. This could be something as simple as a Role field as a string on your users table e.g. Admin or Basic, or even a boolean is_admin field.
This would give you the ability to implement a Policy or Middleware to prevent basic users accessing the admin panel, and you can have permission checks to ensure a user can't update other users posts etc.
If you don't foresee needing anything more complex in future then this would suffice. However, as your app becomes more mature, you might wish to have a more advanced roles system, for example where a user needs to have multiple roles.
You don't necessarily need to define a role for every user...
It's probably a good idea to, however, you can 'hardcode' and make some assumptions about some of the access...
For example:
If you assume that anyone who is logged in can make a post and can edit their own post, you don't need to make a role for users to say "can_make_post", just have a check saying "if user is logged in, then let them make a post"
then if you say, have an admin area, then you can go "if user a has role
with the 'admin_access' permission, then allow access"
It would be a good idea to have roles for everything, as it allows more customisation, however, your the one designing it, if you don't need the customisation, you can probably just make some assumptions like above.

How do I manage two different authentication in Laravel?

since laravel's built in authentication uses user model? For example I want to separate the admin from the user so I will build two different layers in my application, the admin and the user. How can I achieve this to laravel since it's default auth uses users table and user model?
In my opinion, there's no real need to separate the two. Administrators and typical users can exist on the same database table, because they are both users but can have different permissions.
It seems like you're just looking for a typical permissions system (ACL). There's multiple packages available that can help you handle this.
Orchestra Auth
Sentinel
Entrust
Normally as an admin is still an user you give them a role column and let say you have : users, moderators and admins. Then you got role 0,1,2 for them. Just make it an enum and if you need to check in Laravel use : Auth::user()->role == 2 for example of admin rights :)

ASP.NET MVC3 / User registration, membership, roles and privilege

In my application I need to register users. The users can be any of three: admin, client and general. They have different attributes (Admin may have only name, client may have company address and so on). The default MVC membership scheme is okay but how can it be extended to register more information during registration time? Or should I use custom membership?
I need to have a record of clients and general users with clientID or generalID.
The default MVC membership scheme is okay but how can it be extended
to register more information during registration time? Or should I use
custom membership?
I think too many people, yourself included, are expecting to get too much from the default ASP.NET Membership Provider. It was never designed to handle application-specific things, like what company your customer works for, your admin's name, and so on. It's main purpose is storing passwords for authentication.
Sure, the password needs to be linked to a username, so that there can be a 2-key authentication pair. Sometimes you also need the user's email address, when it is different from their username, in order to contact the user regarding their password. But don't store anything else about your users in the membership store. Store it in your application database.
In order to join data between your application and the membership provider, use the membership provider's UserName or ProviderKey as a column in one of your database tables. You end up with 2 entities which are not explicitly related. You can even have your SqlMembershipProvider implemented in a separate database from your application database. Even if they are in the same database, avoid having a foreign key between any of the provider tables and your application tables. This muddies the waters between what you own, and what you "outsource" to the membership provider.
You end up with 2 physically isolated representations of your user. One is the MembershipProvider, which contains a password for your user. The other is your application, which contains other business-specific details. The two are only logically associated within your application. After you authenticate a user with the membership API, their UserName and/pr ProviderKey become available to your application. You can then use that piece of data to query your app database and get the additional details. This is where you might put something like the clientID or generalID you mentioned.
If you look at the System.Web.Security.Member* API, this should make things clearer. It does one thing really well -- associating your users with passwords and other information related to password resetting (like the email address, question and answer, etc). So outsource just the password provider, and rely on your application to do the important stuff.
You could customise the default profile provider or create your own... Follow this reference
http://msdn.microsoft.com/en-us/library/8zs47k7y
You can add new properties to the profile for anything in the web.config too
I highly suggest creating your own membership roles. It's dead simple and nothing can beat the flexibility of having your own implementation.
Here's a video I made a while back showing you step by step how to achieve this:
http://www.youtube.com/watch?v=BsxUsyMSGeA
The gist of it is, you create your own AuthorizeAttribute and create your own roles; protecting each controller or even individual Action methods along the way.
The one drawback of this approach is that you can determine what Role a user has in your system, but not what a Role can do in your system. Does that make sense?
There are other choices if you need to edit what a role can do at runtime.

Resources