Collin Njuguna
Collin Njuguna

Reputation: 13

Call to a member function hasRole() on null

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

Upvotes: 0

Views: 11281

Answers (2)

Ngugi Kiarie
Ngugi Kiarie

Reputation: 1448

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

Upvotes: 0

Saeed
Saeed

Reputation: 134

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.

Upvotes: 2

Related Questions