Laravel 12 JWT Roles & Permissions API – Step by Step Guide

In modern API development, security and access control are essential. In Laravel 12, you can combine JWT authentication for secure login & token handling with Spatie Laravel Permission for flexible role and permission management.

This guide walks you through building a secure, RESTful API in Laravel 12.

Key Features

  • JWT Authentication → Token-based login system

  • Role & Permission Management → Using Spatie Laravel Permission

  • Clean RESTful Endpoints → Following Laravel conventions

API Endpoints

MethodEndpointPurpose
GET/api/rolesList all roles
POST/api/rolesCreate role
GET/api/roles/{id}Show role details
PUT/api/roles/{id}Update role
DELETE/api/roles/{id}Delete role
GET/api/permissionsList permissions
POST/api/permissionsCreate permission

Step 1: Install Spatie Laravel Permission

composer require spatie/laravel-permission

Publish the config & migration:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" php artisan migrate

Step 2: Update User Model

app/Models/User.php

use Spatie\Permission\Traits\HasRoles; class User extends Authenticatable { use HasRoles; protected $fillable = [ 'name', 'email', 'password', ]; }

This enables users to be assigned roles and permissions.

Step 3: Create Controllers

php artisan make:controller Api/RoleController --api php artisan make:controller Api/PermissionController --api

Step 4: RoleController

app/Http/Controllers/Api/RoleController.php

<?php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Spatie\Permission\Models\Role; class RoleController extends Controller { public function index() { return response()->json(Role::all(), 200); } public function store(Request $request) { $validated = $request->validate([ 'name' => 'required|string|unique:roles,name', ]); $role = Role::create(['name' => $validated['name']]); return response()->json($role, 201); } public function show($id) { $role = Role::findOrFail($id); return response()->json($role, 200); } public function update(Request $request, $id) { $role = Role::findOrFail($id); $validated = $request->validate([ 'name' => 'required|string|unique:roles,name,' . $role->id, ]); $role->update(['name' => $validated['name']]); return response()->json($role, 200); } public function destroy($id) { $role = Role::findOrFail($id); $role->delete(); return response()->json(['message' => 'Role deleted successfully'], 200); } }

Step 5: PermissionController

app/Http/Controllers/Api/PermissionController.php

<?php namespace App\Http\Controllers\Api; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Spatie\Permission\Models\Permission; class PermissionController extends Controller { public function index() { return response()->json(Permission::all(), 200); } public function store(Request $request) { $validated = $request->validate([ 'name' => 'required|string|unique:permissions,name', ]); $permission = Permission::create(['name' => $validated['name']]); return response()->json($permission, 201); } }

Step 6: Define Routes

routes/api.php

use App\Http\Controllers\Api\RoleController; use App\Http\Controllers\Api\PermissionController; Route::middleware('auth:api')->group(function () { // Roles Route::apiResource('roles', RoleController::class)->except(['create', 'edit']); // Permissions Route::get('/permissions', [PermissionController::class, 'index']); Route::post('/permissions', [PermissionController::class, 'store']); });

👉 Using Route::apiResource ensures RESTful Laravel conventions.

Step 7: Test with Postman

Always send the JWT token in the header:

Authorization: Bearer {JWT_TOKEN}

1. List Roles

GET /api/roles

2. Create Role

POST /api/roles Body (JSON): { "name": "Admin" }

3. Show Role

GET /api/roles/1

4. Update Role

PUT /api/roles/1 Body (JSON): { "name": "Editor" }

5. Delete Role

DELETE /api/roles/1

6. List Permissions

GET /api/permissions

7. Create Permission

POST /api/permissions Body (JSON): { "name": "edit articles" }

✅ Conclusion

You now have a Laravel 12 API with:

  • 🔑 JWT authentication

  • 👥 Spatie Permission roles & permissions

  • 🛠️ Clean RESTful controllers & routes

  • 🧪 Postman-tested endpoints

This structure is scalable, secure, and production-ready.

Want the full source code?

Download the complete Laravel 12 JWT API Authentication example on my GitHub repo here.

Happy Coding!

Souy Soeng

Souy Soeng

Hi there 👋, I’m Soeng Souy (StarCode Kh)
-------------------------------------------
🌱 I’m currently creating a sample Laravel and React Vue Livewire
👯 I’m looking to collaborate on open-source PHP & JavaScript projects
💬 Ask me about Laravel, MySQL, or Flutter
⚡ Fun fact: I love turning ☕️ into code!

Post a Comment

CAN FEEDBACK
Ad