0
votes

I am new to Laravel

I have set up permissions and roles inside my application, and assigned these to users - however when I try to use hasRole or hasAnyRole it isn't working for me.

Here is my 'CheckRole' middleware:

<?php

namespace App\Http\Middleware;

use Closure;

class CheckRole
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // Get the required roles from the route
        $roles = $this->getRequiredRoleForRoute($request->route());
        // Check if a role is required for the route, and
        // if so, ensure that the user has that role.
        if($request->user()->hasRole('Admin','Receiptionist','Manager','CEO','Root')
        {
            return $next($request);
        }
        return response([
            'error' => [
                'code' => 'INSUFFICIENT_ROLE',
                'description' => 'You are not authorized to access this resource.'
            ]
        ], 401);
    }
    private function getRequiredRoleForRoute($route)
    {
        $actions = $route->getAction();
        return isset($actions['roles']) ? $actions['roles'] : null;
    }
}

Here is my user model:

public function role()
{
    return $this->belongsToOne('App\Role', 'id', 'role_id');
}
public function hasRole($roles)
{
    $this->have_role = $this->getUserRole();
    // Check if the user is a root account
    if($this->have_role->name == 'Root') {
        return true;
    }
    if(is_array($roles)){
        foreach($roles as $need_role){
            if($this->checkIfUserHasRole($need_role)) {
                return true;
            }
        }
    } else{
        return $this->checkIfUserHasRole($roles);
    }
    return false;
}
private function getUserRole()
{
    return $this->role()->getResults();
}
private function checkIfUserHasRole($need_role)
{
    return (strtolower($need_role)==strtolower($this->have_role->name)) ? true : false;
}

And here is my Role model:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Role extends Model


{
      protected $table = 'role';
      protected $fillable = ['name'];
      protected $primaryKey = 'id';
      public $timestamps = false;
public function users()
{
    return $this->belongsToMany('App\User', 'role_id', 'id');
}
}

I am trying to run this route:

Route::group(['middleware'=>['authen','roles'],'roles'=>['Root']],function(){
//for Root

Route::get('/createUser',function(){
    echo "This is for Root test";
});

which is producing this error:

FatalThrowableError (E_ERROR) Call to a member function hasRole() on null

2
This error implies, you are trying to access a user instance that does not exist in the incoming request ($request->user()->hasRole). looking at your /createUser route, this implies you are creating a new user no? request->user(), returns the currently authenticated user. If you are creating a new user, it implies, no currently logged in user, i would assume. Thus $request->user(), would be a null value. Confirm if you're trying to create a new user or notMGS

2 Answers

1
votes

If your code worked on first time then try to add into Kernel.php one line and will be everything all right I guess. Have nice code working on your project. :)

protected $middlewareGroups = [
    'CheckRole' => [
      \App\Http\Middleware\CheckRole::class,
      \Illuminate\Auth\Middleware\Authenticate::class,
],

It means that you are trying to check the role of the user but you are not logged in before that method that is the reason that you are getting null.

0
votes

I had the same issue, turns out the I was calling the middleware even when the user was not logged in, meaning that the Auth::user() or in your case $request->user() was empty.

Might I suggest you ensure that the user is logged in