I have an app with a Users table with columns: id|name|email|is_admin
. I want admins to be able to set other users as admins.
In models/User.php
I prevent mass-assignment with:
protected $fillable = ['name', 'email'];
Laravel 4 Role Based Mass Assignment concludes that Laravel has no such feature.
My question is, what is a viable work-around? How can I allow only admins to update the column 'is_admin' in my database?
Mass Assignment in Laravel refers to assigning values to model attributes in bulk, in the form of an array ["title" => "ttl", "slug" => "slg", "excerpt" => "exrpt", "body" => "bdy"], in the create (), update () or fill () methods. A malicious user can pass a field in an HTTP request that can unexpectedly alter value in your database table column.
Each database table is mapped to a Model class which is used for interacting with that table. Let's break down this word. In order to make developers life easier, Eloquent ORM offers Mass Assignment functionality which helps them assign (insert) large number of input to database.
Mass assignment is a process of sending an array of data that will be saved to the specified model at once. In general, you don’t need to save data on your model on one by one basis, but rather in a single process. Mass assignment is good, but there are certain security problems behind it.
Laravel Eloquent ORM provides a simple API to work with database. It is an implementation of Active Record pattern. Each database table is mapped to a Model class which is used for interacting with that table. Let's break down this word.
Actually, the following code:
protected $fillable = ['name', 'email'];
will prevent from Mass-Assignment
which means that, someone can't use something like this:
User::create(['name' => 'xxx', 'email' =>'[email protected]', 'is_admin' => 1]);
In this case, the is_admin
field won't be updated but it's still possible do the same thing using something like this (it's not Mass Assignment
):
$user = User::find($id); // Or $user = new User; (when creating a new user);
$user->name = 'xxx';
$user->email = '[email protected]';
$user->is_admin = 1;
$user->save();
So there will be no problem to update the User
like this way.
Extend your User model to create an admin-only version without the mass-assignment protection.
In the new class, override the $fillable
property:
class UnprotectedUser extends User
{
protected $fillable = [<all fields>];
}
Then use the new model in your admin-specific code:
$user = UnprotectedUser::create($arrayOfAllFields);
Be sure to use the original class in as many places as possible so that you can continue to take advantage of the mass-assignment protection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With