Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Role Based Jwt Auth Laravel Package

shahzadbarkati/role-based-jwt-auth

View on GitHub
Deep Wiki
Context7

JWT Auth Package for Laravel

A lightweight, role-based JWT authentication package for Laravel 12. Built with SOLID principles, it provides secure API endpoints for login, logout, token refresh, profile management, password reset (with email codes), and password updates. Tokens are invalidated on new logins/refreshes for enhanced security.

Features

  • JWT Authentication: Powered by tymon/jwt-auth with configurable TTL and blacklisting.
  • Role-Based Access: Middleware for roles like admin, user. Supports many-to-many relationships.
  • Token Management: Auto-invalidate previous tokens (configurable max per user).
  • Password Handling: Forgot/reset with 6-digit codes (10-min expiration, customizable) via email.
  • Endpoints: Login, logout, refresh, profile, forgot-password, reset-password, update-password.
  • Easy Integration: Uses existing users table; optional migrations for roles/tokens.
  • Configurable: Full config for TTLs, guards, emails, routes, etc.

Requirements

  • PHP 8.2+
  • Laravel 12.0+
  • Database (MySQL/PostgreSQL/SQLite) for tokens/resets/roles.
  • Mail configuration for password resets (e.g., SMTP).

Installation

1. Require the Package

composer require shahzadbarkati/role-based-jwt-auth

This auto-registers the service provider via Laravel's package discovery.

2. Publish Assets

Publish the config, migrations, views, and trait:

php artisan vendor:publish --provider="ShahzadBarkati\RoleBasedJwtAuth\Providers\JwtAuthServiceProvider" --tag="jwt-auth"

This creates:

  • config/jwt-auth.php: Core configuration.
  • database/migrations/: Migrations for roles, pivot, and JWT tokens.
  • resources/views/vendor/jwt-auth/emails/password-reset.blade.php: Email template.
  • app/Traits/HasRoles.php: Trait for your User model.

3. Generate JWT Secret

Run the command to auto-generate and add JWT_SECRET (and suggested TTLs) to your .env:

php artisan jwt:secret

Example output:

textJWT_SECRET=base64:<your_generated_key>
Also set JWT_TTL=60
JWT_REFRESH_TTL=20160
PASSWORD_RESET_TTL=10
JWT_BLACKLIST_ENABLED=true

4. Run Migrations

The package prompts for migrations on first boot (in console). If skipped, run manually: Check if Migrations Are Needed:

If you have an existing users table: ✅ (package uses it). For roles/tokens: New tables (roles, role_user, jwt_tokens).

Interactive Prompt (Recommended):

php artisan jwt-auth:migrate-prompt
  • This asks: "Run migrations for roles and tokens? (Y/N)"
  • Y: Automatically runs php artisan migrate (adds tables without overwriting existing data).
  • N: Skip; proceed to manual run below.

Manual Run (Alternative):

php artisan migrate

Optional: Add Indexes (for performance):

Run these after migration:

-- In your DB tool
ALTER TABLE jwt_tokens ADD INDEX idx_user_id (user_id);
ALTER TABLE jwt_tokens ADD INDEX idx_jti (jti);
ALTER TABLE jwt_tokens ADD INDEX idx_expires_at (expires_at);
ALTER TABLE password_resets ADD INDEX idx_email (email);

5. Configure Your User Model

Add the published HasRoles trait and JWT settings to app/Models/User.php:

<?php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use ShahzadBarkati\RoleBasedJwtAuth\Traits\HasRoles;  // Import the trait
use Tymon\JWTAuth\Contracts\JWTSubject;  // import

class User extends Authenticatable implements JWTSubject
{
    use HasRoles, Notifiable;  // Use the trait

    // ... (rest of your User model unchanged)

    // Required for JWT: Return the ID claim
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    // Required for JWT: Return custom claims (e.g., add roles here if needed)
    public function getJWTCustomClaims()
    {
        return [
            'roles' => $this->roles->pluck('slug')->toArray(),  // Optional: Include roles in token
        ];
    }
}

This adds roles(), hasRole($role), assignRole($role), and removeRole($role) methods.

6. Configure Mail (for Password Resets)

Update .env for your mail driver (e.g., SMTP):

MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=your-email@example.com
MAIL_PASSWORD=your-password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@example.com
MAIL_FROM_NAME="${APP_NAME}"

Test: php artisan tinker then

Mail::raw('Test', function ($message) { 
    $message->to('test@example.com'); 
});

7. Update Auth Config (Optional)

The package merges JWT guards. Verify config/auth.php:

'guards' => [
    ...., 

    'api' => [
        'driver' => 'jwt',  // Added by package
        'provider' => 'users',
    ],
],

Configuration

Edit config/jwt-auth.php for customizations:

  • JWT: TTL (60min default), refresh TTL (2 weeks), algo (HS256).
  • Guards: API guard settings.
  • Roles: Table names, default role, available roles array.
  • Password Reset: Code length (6), TTL (10min), email template/from.
  • Routes: Prefix (api/auth), middleware (api).
  • Token auto invalidate if regenerate by login or refresh.

Usage

Routes

Routes are auto-loaded at /api/auth (configurable). View with php artisan route:list.

Request/Response Examples:

  • Login
// Request
{
  "email": "user@example.com",
  "password": "password"
}
// Response
{
  "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."
}
  • Profile
// Response
{
  "id": 1,
  "email": "user@example.com",
  "roles": ["user"]
}
  • Forgot Password
// Request
{
  "email": "user@example.com"
}
// Email sent: "Your reset code is: 123456 (expires in 10 mins)"
  • Reset Password
// Request
{
  "email": "user@example.com",
  "code": "123456",
  "password": "newpassword",
  "password_confirmation": "newpassword"
}
// Response
{
  "message": "Password reset"
}

Role-Based Routes

Protect routes with role:slug middleware:

// In routes/api.php
Route::middleware(['auth:api', 'role:admin'])->get('/admin/dashboard', function () {
    return 'Admin only';
});

Assign Roles (e.g., in Seeder/Controller):

$user = User::find(1);
$user->assignRole('admin');  // Or Role::create(['name' => 'Admin', 'slug' => 'admin']); $user->assignRole($role);

Facade Usage

For custom logic:

use ShahzadBarkati\RoleBasedJwtAuth\Facades\JwtAuth;

$token = JwtAuth::login(['email' => 'user@example.com', 'password' => 'pass']);
JwtAuth::logout($token);

Seeding Roles (Optional)

Create a seeder: php artisan make:seeder RoleSeeder

<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;
use ShahzadBarkati\RoleBasedJwtAuth\Models\Role;

class RoleSeeder extends Seeder
{
    public function run(): void
    {
        $roles = ['admin', 'user', 'moderator'];
        foreach ($roles as $role) {
            Role::firstOrCreate(['slug' => $role], ['name' => ucfirst($role)]);
        }
    }
}

Run: php artisan db:seed --class=RoleSeeder

Testing

  • Add to phpunit.xml: <env name="JWT_SECRET" value="base64:your_test_key"/>
  • Create tests for endpoints (e.g., using actingAs with JWT).
  • Run: php artisan test

Example Test:

uses(RefreshDatabase::class)->in(__DIR__);

$response = $this->postJson('/api/auth/login', [
        'email' => 'test@example.com',
        'password' => 'password',
    ]);

    // Assert: Success response with token
    $response
        ->assertStatus(200)
        ->assertJsonStructure([
            'token' => ['*'],
        ]);

    // Verify token is a string
    expect($response->json('token'))->toBeString();

Security Notes

  • Always validate inputs (built-in).
  • Use HTTPS for tokens.
  • Rotate secrets in production.
  • For high load, queue emails and use Redis for blacklists.

Contributing

  • Fork, branch, PR with tests.
  • Run composer test and php artisan cs:fix (Pest/PHPStan).

License

MIT. See LICENSE for details.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours