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

Easy Api Jwt Authentication Laravel Package

citizen63000/easy-api-jwt-authentication

Lightweight Laravel package for simple JWT-based API authentication. Adds helpers to issue and validate tokens for protected routes and user sessions, aiming to reduce boilerplate when securing APIs with JSON Web Tokens.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require citizen63000/easy-api-jwt-authentication
    

    Publish the package configuration and migrations:

    php artisan vendor:publish --provider="Citizen63000\EasyApiJwtAuthentication\EasyApiJwtAuthenticationServiceProvider"
    php artisan migrate
    
  2. Configuration: Update .env with JWT settings (e.g., JWT_SECRET, JWT_TTL). The package provides defaults in config/easy-api-jwt-authentication.php.

  3. First Use Case:

    • Authenticate a User:
      use Citizen63000\EasyApiJwtAuthentication\Facades\JwtAuth;
      
      $token = JwtAuth::login(['email' => 'user@example.com', 'password' => 'password']);
      
    • Protect a Route: Add middleware to routes/api.php:
      Route::middleware(['auth:api'])->group(function () {
          Route::get('/user', function () {
              return response()->json(auth()->user());
          });
      });
      
  4. Testing: Use the provided AuthenticationTestTrait in tests/Feature/AuthTest.php:

    use Citizen63000\EasyApiJwtAuthentication\Tests\AuthenticationTestTrait;
    
    class AuthTest extends TestCase
    {
        use AuthenticationTestTrait;
    
        public function test_login()
        {
            $this->testRefreshToken();
        }
    }
    

Implementation Patterns

Core Workflows

  1. Authentication Flow:

    • Login: Use JwtAuth::login() with user credentials.
    • Refresh Token: Implement JwtAuth::refresh() for token rotation.
    • Logout: Call JwtAuth::logout() to invalidate tokens (if using blacklist).
  2. API Integration:

    • Guard Integration:
      // config/auth.php
      'guards' => [
          'api' => [
              'driver' => 'jwt',
              'provider' => 'users',
          ],
      ],
      
    • Custom Claims: Extend JWT payload via middleware:
      namespace App\Http\Middleware;
      
      use Citizen63000\EasyApiJwtAuthentication\Facades\JwtAuth;
      use Closure;
      
      class AddCustomClaims
      {
          public function handle($request, Closure $next)
          {
              JwtAuth::setCustomClaims(['role' => auth()->user()->role]);
              return $next($request);
          }
      }
      
  3. Validation:

    • Use built-in validators for login requests:
      use Citizen63000\EasyApiJwtAuthentication\Requests\LoginRequest;
      
      Route::post('/login', [LoginRequest::class, 'handle']);
      
  4. Rate Limiting:

    • Apply throttling to auth endpoints:
      Route::middleware(['throttle:60,1'])->group(function () {
          Route::post('/login', [LoginRequest::class, 'handle']);
      });
      

Advanced Patterns

  1. Multi-Tenant JWTs:

    • Override JwtAuth::generateToken() to include tenant ID:
      $token = JwtAuth::generateToken([
          'user_id' => auth()->id(),
          'tenant_id' => request()->tenant_id,
      ]);
      
  2. Social Logins:

    • Extend LoginRequest to handle OAuth tokens:
      public function authorize()
      {
          return $this->validate([
              'token' => 'required|string',
              'provider' => 'required|in:google,github',
          ]);
      }
      
  3. Event Listeners:

    • Listen for token generation/refresh:
      // EventServiceProvider
      protected $listen = [
          \Citizen63000\EasyApiJwtAuthentication\Events\TokenGenerated::class => [
              \App\Listeners\LogTokenActivity::class,
          ],
      ];
      
  4. Testing:

    • Mock JWT auth in unit tests:
      $this->actingAsUser($user, 'api')
           ->withHeaders(['Authorization' => 'Bearer ' . $token]);
      

Gotchas and Tips

Pitfalls

  1. Token Blacklisting:

    • If using JwtAuth::logout(), ensure the blacklist table exists and is indexed. Without it, tokens won’t be revoked.
    • Fix: Run php artisan migrate after publishing the package.
  2. Clock Skew:

    • JWTs rely on server time. If clocks are misaligned (>5 minutes), tokens may fail validation.
    • Fix: Use a time synchronization service (e.g., NTP) or implement JwtAuth::setLeeway():
      JwtAuth::setLeeway(30); // 30 seconds
      
  3. Password Hashing:

    • The package assumes Laravel’s default bcrypt hashing. If using argon2, update the users table migration:
      $table->string('password')->nullable()->change();
      
  4. CORS Issues:

    • JWTs sent via Authorization: Bearer may be blocked by CORS. Ensure your frontend includes:
      fetch('/api/user', {
          headers: {
              'Authorization': 'Bearer ' + token,
              'Accept': 'application/json',
          },
          credentials: 'include',
      });
      
  5. PHP 8 Strict Types:

    • If enabling strict_types=1 in composer.json, ensure all methods returning array or mixed are updated to use PHP 8 return types (e.g., array<int, string>).

Debugging Tips

  1. Token Validation Errors:

    • Enable debug mode in config/easy-api-jwt-authentication.php:
      'debug' => env('APP_DEBUG', false),
      
    • Check logs for TokenInvalidException or TokenExpiredException.
  2. Middleware Order:

    • Ensure auth:api middleware runs after throttle and before bindings:
      Route::middleware(['throttle:60,1', 'auth:api'])->group(...);
      
  3. Database Locks:

    • High concurrency may cause lock wait timeout on the blacklist table. Add indexes:
      Schema::table('blacklist', function (Blueprint $table) {
          $table->index('token');
      });
      

Extension Points

  1. Custom Token Storage:

    • Override JwtAuth::storeToken() to use Redis or DynamoDB:
      public function storeToken($token, $user)
      {
          Redis::set("jwt:{$user->id}", $token, 'EX', 24 * 60 * 60);
      }
      
  2. Dynamic TTL:

    • Adjust token expiry based on user role:
      $ttl = auth()->user()->role === 'admin' ? 86400 : 3600; // 1 day vs 1 hour
      JwtAuth::setTtl($ttl);
      
  3. Algorithm Flexibility:

    • Switch from HS256 to RS256 (RSA) for better security:
      'algorithm' => 'RS256',
      'private_key' => storage_path('app/rsa_private.pem'),
      'public_key' => storage_path('app/rsa_public.pem'),
      
  4. Event Customization:

    • Extend TokenGenerated event to add metadata:
      class CustomTokenGenerated extends TokenGenerated
      {
          public function __construct($token, $user, $customData = [])
          {
              parent::__construct($token, $user);
              $this->customData = $customData;
          }
      }
      

Configuration Quirks

  1. Environment Variables:

    • The package expects JWT_SECRET to be 32+ characters for HS256. Use:
      openssl rand -hex 32
      
    • For RS256, generate keys with:
      openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:2048
      openssl pkey -in rsa_private.pem -pubout -out rsa_public.pem
      
  2. Caching:

    • Disable JWT_CACHE if using Redis for token storage to avoid double storage.
  3. Logging:

    • Enable JWT_LOG_FAILED_ATTEMPTS to track brute-force attempts:
      'log_failed_attempts' => env('JWT_LOG_FAILED', false),
      

Performance Tips

  1. Token Size:
    • Reduce payload size by excluding unnecessary claims (e.g., iat, nbf):
      JwtAuth::setClaims(['sub' => $user->id, 'role' => $user->role]);
      

2

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.
graham-campbell/flysystem
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
directorytree/opensearch-client
directorytree/opensearch-adapter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin