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

Jwt Auth Bundle Laravel Package

dimkinthepro/jwt-auth-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require dimkinthepro/jwt-auth-bundle
    

    Add to config/bundles.php (Symfony):

    return [
        // ...
        DimkinThePro\JwtAuthBundle\DimkinTheProJwtAuthBundle::class => ['all' => true],
    ];
    
  2. Configuration Publish the default config:

    php bin/console dimkin-the-pro:jwt-auth:install
    

    Edit config/packages/dimkin_the_pro_jwt_auth.yaml:

    dimkin_the_pro_jwt_auth:
        secret_key: '%env(JWT_SECRET_KEY)%'  # Generate via `openssl rand -hex 32`
        expiration_time: 3600  # 1 hour in seconds
    
  3. First Use Case Generate a token in a controller:

    use DimkinThePro\JwtAuthBundle\Service\JwtService;
    
    class AuthController extends AbstractController {
        public function login(JwtService $jwtService, UserRepository $userRepo) {
            $user = $userRepo->findOneBy(['email' => 'user@example.com']);
            $token = $jwtService->generateToken($user);
            return $this->json(['token' => $token]);
        }
    }
    
  4. Protect Routes Add to security.yaml:

    firewalls:
        api:
            pattern: ^/api
            jwt: ~
    

Implementation Patterns

Common Workflows

1. Token Generation & Validation

  • Generate Token (e.g., after login):
    $token = $jwtService->generateToken($user, ['role' => 'admin']); // Custom claims
    
  • Validate Token (automatically handled by firewall, but manual check):
    $jwtService->validateToken($request->headers->get('Authorization'));
    

2. Custom Claims

Extend token payload dynamically:

$token = $jwtService->generateToken($user, [
    'custom_claim' => 'value',
    'exp' => time() + 86400, // Override expiration
]);

3. Refresh Tokens

Implement a refresh endpoint:

public function refresh(JwtService $jwtService, Request $request) {
    $refreshToken = $request->get('refresh_token');
    $newToken = $jwtService->refreshToken($refreshToken);
    return $this->json(['token' => $newToken]);
}

4. Integration with Symfony Security

  • User Provider:
    security:
        providers:
            jwt:
                entity: { class: App\Entity\User }
                property: email
    
  • Custom User Loader (for non-DOCTRINE users):
    use DimkinThePro\JwtAuthBundle\Security\User\JwtUserProvider;
    
    services:
        App\Security\CustomUserProvider:
            parent: DimkinThePro\JwtAuthBundle\Security\User\JwtUserProvider
            arguments: ['@App\Service\CustomUserLoader']
    

5. Middleware for Non-API Routes

Use the JwtListener manually:

use DimkinThePro\JwtAuthBundle\EventListener\JwtListener;

public function onKernelRequest(GetResponseEvent $event) {
    $listener = new JwtListener($jwtService);
    $listener->onKernelRequest($event);
}

Best Practices

  • Store Tokens Securely: Use HttpOnly cookies or Authorization: Bearer headers.
  • Short-Lived Tokens: Combine with refresh tokens (implement refreshToken()).
  • Logging: Log token generation/validation for auditing:
    $jwtService->setLogger($logger);
    

Gotchas and Tips

Pitfalls

  1. Secret Key Management

    • Issue: Hardcoded secrets in config.
    • Fix: Always use %env(JWT_SECRET_KEY)% and rotate keys periodically.
    • Debug: If tokens fail, check JWT_SECRET_KEY is set in .env.
  2. Time Skew

    • Issue: Tokens expire due to server clock drift.
    • Fix: Configure leeway in jwt_auth.yaml:
      leeway: 60  # 60 seconds buffer
      
  3. Refresh Token Logic

    • Issue: No built-in refresh token handling.
    • Fix: Implement manually (see workflow) or use a library like lexik/jwt-auth-bundle for advanced features.
  4. Custom User Providers

    • Issue: Default assumes Doctrine users.
    • Fix: Extend JwtUserProvider or implement UserInterface:
      class CustomUser implements UserInterface {
          public function getRoles() { ... }
          public function getPassword() { ... }
          // ...
      }
      
  5. CORS Headers

    • Issue: Missing Authorization header in preflight requests.
    • Fix: Configure CORS to include Authorization:
      # config/packages/nelmio_cors.yaml
      paths:
          '^/api/*':
              methods: [GET, POST, PUT, DELETE]
              headers: ['Authorization']
      

Debugging

  • Token Decoding:

    php bin/console debug:jwt "your.token.here"
    

    (Note: Requires custom script; no built-in command exists.)

  • Common Errors:

    Error Cause Solution
    Invalid token Wrong secret key or malformed token Verify JWT_SECRET_KEY and token format
    Token not found Missing Authorization header Check request headers
    User not found User provider misconfiguration Debug JwtUserProvider
    Expired token Clock skew or short expiration_time Adjust leeway or token TTL

Extension Points

  1. Custom Token Fields Override JwtService to add fields:

    class CustomJwtService extends JwtService {
        protected function getPayload(UserInterface $user, array $customClaims = []) {
            $payload = parent::getPayload($user, $customClaims);
            $payload['uid'] = $user->getId(); // Example
            return $payload;
        }
    }
    
  2. Event Listeners Extend token logic via events:

    use DimkinThePro\JwtAuthBundle\Event\JwtEvents;
    
    $dispatcher->addListener(JwtEvents::TOKEN_CREATED, function ($event) {
        $event->getToken()->set('audit', 'login');
    });
    
  3. Non-Symfony Integration Use the JwtEncoder/JwtDecoder services directly:

    $encoder = $container->get('dimkin_the_pro_jwt_auth.encoder');
    $token = $encoder->encode(['data' => 'value'], $secretKey);
    

Configuration Quirks

  • Default Expiration: Hardcoded to 3600 (1 hour) if not set.
  • Algorithm: Uses HS256 by default (no option to change).
  • Cookie Support: Not built-in; use lexik/jwt-auth-bundle for cookies.
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.
directorytree/privacy-filter-classifier
directorytree/privacy-filter
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
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony
spatie/flare-daemon-runtime