James Martin-Davies
James Martin-Davies

Reputation: 651

Laravel 4.2 User Role Security

I've been tinkering with my own user authorisation and providing user roles based on a database entry for my users.

I made two roles; a user role which is just a general, signed up user, and an author role, which is obviously for an author.

In my users table migration, I'm using $table->string('role')->default('user'); as the default user role. I can then decide from a form somewhere if the user should be an author.

In my User.php, I set up a public function that calls the role database entry in my users table, like so:

public function isAuthor()
{
    if (Auth::guest()) return false;
    return Auth::user()->role = $this->role == 'author';
}

Which I can now call in my templates, like so:

@if($user->isAuthor())
    <p>Only the author can this!</p>
@endif

This gives me the control I expect, but I'm not entirely sold on the fact 'it's that easy'. I understand that yes, I can create a relationship with the User and bind the relationship between two models, but I found this pretty neat. My only worry on this is security.

This may not be best practise by a long shot, but I'm fairly new to Laravel and was wondering what security implications doing it the way I have done vs. other methods available.

I totally understand that there are other methods on SO/Laravel Docs and User roles have been the topic of many discussions, though, I've never seen it the way I've implemented it (which worries me). I just noticed that I could check the current user is signed in using the above method and thought that querying the DB for matched string would work the same -- and it does.

My question is, is this safe enough to use in the real world?

Upvotes: 0

Views: 900

Answers (1)

Everon
Everon

Reputation: 3879

It looks like you're just using a varchar field in your database and hard coding your permissions around it. I propose a better structure.

table: users
columns: id:int, role_id:int username:varchar64 password:varchar64 etc

table: roles
columns id:int, name:varchar64, description:varchar64 etc etc...

table: permissions
columns: id:int, name:varchar64

table:roles_permissions
columns: role_id:int, permission_id:int

Here we have four tables, one for users, user roles, permissions and a join pivot table for a many to many relationship between roles and permissions. This is the basis for any RBPS (role based permission system).

Each user can have one role

A role can have 0 or many permissions

By this concept we can reuse roles over and over or even make a user have many roles with an extra join table is applicable.

All permissions would be stored like so: id:1, name:can_login

If the can_login relation is present on a user's role is present, he can login. Some mock code.

if(Auth::can('can_login'))
{
    //Log me in etc etc
}

The advantage of using the database is that we don't repeat ourselves with permission logic which is a design principle in of its self.

This type of functionality has been provided again and again and I suggest you look at Entrust and Confide for Laravel as they provide all of this out of the box for you.

On the other hand if you're doing this to learn then keep going!

Upvotes: 1

Related Questions