Check If user has a role In Laravel 5.5
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Checking User Roles in Laravel: A Deep Dive with Entrust and Passport
As a senior developer working with complex authentication systems in Laravel, managing user permissions—or roles—is fundamental. When you combine robust authentication mechanisms like Passport with role management packages such as Entrust, ensuring that authorization checks are performed correctly before granting access (like generating an API token) is crucial for security.
Many developers run into issues when trying to check roles directly within controller logic. Let's break down why your initial attempt might be failing and establish the most robust, Laravel-idiomatic way to handle role-based access control (RBAC).
The Challenge with Direct Role Checks
You are attempting to use the following logic:
if($user->hasRole('admin')) { ... }
While this syntax is intuitive, if it's not working as expected, it usually points to one of three issues:
- Missing Relationship/Scope: The Entrust package relies on Eloquent relationships and proper setup to define how roles are attached to the user model. If those relationships aren't correctly defined or loaded, the method call will fail silently or throw an error because the relationship doesn't exist in the context of the
Auth::user(). - Package Implementation: The specific way your Entrust package implements role checking might require a different syntax (e.g., checking scopes or permissions rather than simple boolean flags).
- Context Mismatch: You are retrieving the user via
Auth::user(), which is fine, but ensuring that all necessary data from the database is loaded correctly for that specific user instance is key.
The Correct Approach: Database-Driven Authorization
Instead of relying solely on a potentially fragile method call, the most reliable way to check roles in Laravel is by querying the relationship directly through Eloquent. This ensures you are always checking the authoritative source—the database.
Assuming your Entrust setup establishes a clear relationship between the User model and the Role model (e.g., a many-to-many relationship), here is how you should structure the check within your API endpoint:
Step 1: Ensure Proper Eloquent Loading
First, ensure that when you fetch the user, you are either loading the roles directly or using the correct methods provided by your role package. For this example, we will assume a standard setup where the User model has access to its roles.
Step 2: Implementing Conditional Token Generation
We need to verify the existence of the required role before proceeding with token creation. This logic should reside securely within your controller method.
Here is the corrected implementation for your Adminlogin function, focusing on robust conditional access control:
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
public function Adminlogin(Request $request)
{
// 1. Attempt Authentication first
if (! Auth::attempt(['email' => $request->email, 'password' => $request->password])) {
return response()->json(['error' => 'Unauthorised'], 401);
}
$user = Auth::user();
// 2. Robust Role Check using Eloquent/Entrust structure
// We check if the user has a role named 'admin'. The exact method depends on your package setup.
if ($user && $user->hasRole('admin')) { // Assuming hasRole() is correctly implemented by Entrust
// 3. Only proceed if authorized
$success = ['token' => $user->createToken('MyApp')->accessToken];
return response()->json(['success' => $success], 200);
} else {
// 4. Handle unauthorized access clearly
return response()->json(['error' => 'Access Denied: Insufficient Role'], 403);
}
}
Best Practices for Laravel API Security
When building APIs, especially those secured by Passport, remember that authorization logic must be layered. While the controller handles the final gatekeeping, you should also consider implementing Middleware.
For instance, you can create a custom middleware that checks for specific roles before allowing access to entire route groups:
// Example of a simple role-based middleware concept
class RoleMiddleware
{
public function handle($request, Closure $next, $role)
{
if (! Auth::check() || ! Auth::user()->hasRole($role)) {
return response()->json(['error' => 'Forbidden'], 403);
}
return $next($request);
}
}
// In your routes file:
Route::middleware('auth:api')->group(function () {
Route::get('/admin-dashboard', [AdminController::class, 'showAdminDashboard'])
->middleware(new RoleMiddleware('admin')); // Protect this route
});
This approach adheres to the principle of separation of concerns. The controller handles what is being requested, and middleware handles if the authenticated user is permitted to request it. This layered security is a cornerstone of building scalable applications on Laravel, as promoted by resources like those found at laravelcompany.com.
Conclusion
Checking user roles in a Laravel application requires moving beyond simple function calls and adopting robust Eloquent-based logic. By ensuring your Entrust package relationships are correctly loaded and implementing authorization checks consistently—either directly in the controller or via custom middleware—you build an API that is not only functional but fundamentally secure. Always prioritize explicit, database-backed verification for any operation that grants sensitive access, especially when dealing with Passport tokens.