Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i pass number to middleware "can" in Laravel Authorization

based on documentation https://laravel.com/docs/5.5/authorization#via-middleware

use App\Post;

Route::put('/post/{post}', function (Post $post) {
    // The current user may update the post...
})->middleware('can:update,post');

the 'post' in 'can:update,post' is variable passed from '{post}'.

im trying to use middleware('can:update,1'). its not working. maybe its search for '$1' variable, how to pass number '1' to 'can' middleware?

update this is the gate:

    Gate::define('update', function ($user, $role){
        $id = $user->id;
        $roles = $user::find($id)->roles()->get();
        $roleid = $roles[0]->pivot->role_id;
        //above code just for get role id, and $role_id is 1
       return $roleid === $role;
    });
like image 589
tonywei Avatar asked Nov 07 '25 07:11

tonywei


2 Answers

Probably you don't have Policy created for Post.

You can create by command:

php artisan make:policy PostPolicy --model=Post

and then implement method update in that policy.

like image 86
highsolutions Avatar answered Nov 09 '25 22:11

highsolutions


I to had this same problem so I did some digging into the 'can' middleware (Which maps to Illuminate\Auth\Middleware\Authorize)

Once in the class we see the following code

 /**
     * Get the model to authorize.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  string  $model
     * @return \Illuminate\Database\Eloquent\Model|string
     */
    protected function getModel($request, $model)
    {
        if ($this->isClassName($model)) {
            return trim($model);
        } else {
            return $request->route($model, null) ?:
                ((preg_match("/^['\"](.*)['\"]$/", trim($model), $matches)) ? $matches[1] : null);
        }
    }

What this means is...

  • If our string passed in is a class name then return that class name
  • If it is not a class name then...
    • 1 Try to get it from the route, then return the route param
    • 2 Try to get the model from the string via the regex "/^['\"](.*)['\"]$/"

So now lets say we have the middleware call of $this->middleware(sprintf("can:create,%s,%s", User::class, Role::SUPPORT));
This will not work because the Role::SUPPORT does not match the regex
To match it we simply need to place the Role::SUPPORT into quotes.
TAKE NOTE OF THE "'" around the second %s $this->middleware(sprintf("can:create,%s,'%s'", User::class, Role::SUPPORT));

To answer your question specifically, quote your '1' value

middleware("can:update,'1'").
like image 26
gofish Avatar answered Nov 09 '25 23:11

gofish



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!