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

Symfony Access Token Laravel Package

digitaldream/symfony-access-token

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation

    composer require digitaldream/symfony-access-token
    

    Ensure your project uses Symfony 5.4+ (Laravel developers: this is a Symfony bundle, but we’ll adapt concepts).

  2. Copy Configs Copy config/packages/access_token.yaml and config/routes/access_token.yaml from the vendor to your project’s config/ directory.

  3. Environment Setup Add these to .env (adjust values as needed):

    JWT_SECRET="your_secure_random_string_here"
    JWT_ISSUER="https://your-app-domain.com"
    JWT_ALGORITHM=HS256
    JWT_EXPIRE_AT="+1 hour"  # Shorter for testing
    
  4. Configure Security Update config/packages/security.yaml:

    security:
        firewalls:
            api:
                pattern: ^/api
                stateless: true
                provider: app_user_provider  # Your Symfony user provider (e.g., `users:` in `security.yaml`)
                user_checker: AccessToken\Security\UserChecker
                access_token:
                    token_handler: AccessToken\Security\AccessTokenHandler
                    failure_handler: AccessToken\Security\AuthenticationFailureHandler
        access_control:
            - { path: ^/api, roles: ROLE_USER }
    
  5. First Use Case Test the default /api/login endpoint:

    curl -X POST http://localhost:8000/api/login \
      -H "Content-Type: application/json" \
      -d '{"username":"test@example.com","password":"password"}'
    

    Expect a JSON response with a token field.


Implementation Patterns

Workflows

1. Token-Based Authentication Flow

  • Login: POST to /api/login with username/password.
  • Protected Routes: Include the token in the Authorization header:
    Authorization: Bearer <token>
    
  • Token Refresh: Extend the bundle or create a custom endpoint using CreateAccessTokenService to issue new tokens.

2. Custom Login Logic

Override the default login route by injecting CreateAccessTokenService:

// src/Controller/CustomLoginController.php
use AccessToken\Services\CreateAccessTokenService;
use AccessToken\Services\UserCredentialsRequest;

class CustomLoginController extends AbstractController {
    public function login(CreateAccessTokenService $tokenService, Request $request) {
        $credentials = new UserCredentialsRequest(
            $request->request->get('username'),
            $request->request->get('password')
        );
        $token = $tokenService->create($credentials);
        return $this->json(['token' => $token]);
    }
}

Register the route in config/routes.yaml:

app_custom_login:
    path: /api/custom-login
    controller: App\Controller\CustomLoginController::login
    methods: POST

3. Integrating with Laravel (Conceptual)

While this is a Symfony bundle, Laravel developers can adapt the logic:

  • Use Laravel Sanctum or Laravel Passport for JWT/OAuth, but borrow the token generation logic from CreateAccessTokenService.
  • Example: Replace Sanctum’s token generation with a custom service mirroring AccessTokenHandler.

4. Token Validation Middleware

Reuse the bundle’s AccessTokenHandler to validate tokens in Laravel middleware:

// app/Http/Middleware/AuthenticateToken.php
public function handle($request, Closure $next) {
    $token = $request->bearerToken();
    if (!$token || !$this->validateToken($token)) {
        return response()->json(['error' => 'Unauthorized'], 401);
    }
    return $next($request);
}

private function validateToken(string $token): bool {
    // Adapt AccessTokenHandler::validate() logic here
    return true/false;
}

Gotchas and Tips

Pitfalls

  1. Environment Variables

    • JWT_SECRET must be long and random (e.g., openssl rand -hex 32). Hardcoded secrets in .env are unsafe in production.
    • JWT_ISSUER should match your production domain (e.g., https://api.yourdomain.com). Mismatches cause validation failures.
  2. User Provider Mismatch Ensure app_user_provider in security.yaml matches your Symfony user provider (e.g., users: config). Laravel equivalent: Ensure your User model is properly configured in Auth::provider().

  3. Token Expiration Default JWT_EXPIRE_AT is +24 hours. For APIs, shorten this (e.g., +1 hour) and implement refresh tokens via a custom endpoint.

  4. Stateless Firewall The api firewall is stateless. If you need session-like behavior, add:

    access_token:
        stateless: false  # Only if you handle sessions manually
    
  5. CORS Issues The bundle doesn’t handle CORS. Add this to your Symfony config or Laravel’s HandleCors middleware:

    # config/packages/nelmio_cors.yaml
    nelmio_cors:
        defaults:
            allow_origin: ["*"]
            allow_methods: ["GET", "POST", "PUT", "DELETE"]
            allow_headers: ["Authorization", "Content-Type"]
            expose_headers: ["Authorization"]
    

Debugging

  1. Token Validation Errors Check the AccessTokenHandler logs or Symfony’s security.event.authentication_failure event for details.

  2. UserChecker Failures If authentication fails silently, enable debug mode and check:

    bin/console debug:event-dispatcher security.event.authentication_failure
    
  3. Route Conflicts If /api/login conflicts with existing routes, override it as shown in the Custom Login Logic section.

Extension Points

  1. Custom Token Claims Extend AccessToken\Entity\AccessToken to add metadata:

    // src/Entity/CustomAccessToken.php
    class CustomAccessToken extends AccessToken {
        private ?string $customClaim;
    
        public function setCustomClaim(string $claim): self {
            $this->customClaim = $claim;
            return $this;
        }
    }
    

    Update CreateAccessTokenService to use your custom class.

  2. Token Storage Save tokens to a database for revocation:

    // src/Repository/AccessTokenRepository.php
    class AccessTokenRepository extends ServiceEntityRepository {
        public function saveToken(AccessToken $token): void {
            $entityManager = $this->getEntityManager();
            $entityManager->persist($token);
            $entityManager->flush();
        }
    }
    
  3. Algorithm Flexibility Change JWT_ALGORITHM to RS256 for asymmetric encryption (requires JWT_KEY as a private/public key pair). Example:

    JWT_ALGORITHM=RS256
    JWT_KEY="file:///path/to/private.pem"
    
  4. Laravel Adaptation For Laravel, create a facade to wrap CreateAccessTokenService:

    // app/Facades/TokenGenerator.php
    public static function generateToken(string $username, string $password): string {
        $service = app(CreateAccessTokenService::class);
        $credentials = new UserCredentialsRequest($username, $password);
        return $service->create($credentials);
    }
    
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.
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
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle