spatie/laravel-url-signer

repository·main·Indexed 20 days ago

https://github.com/spatie/laravel-url-signer

A Laravel package for creating URLs with a limited lifetime using expiration timestamps and cryptographic signatures. It supports cross-app URL signing and signing of arbitrary URLs, providing more flexibility than native Laravel route signing. Includes the UrlSigner facade for signing and validating URLs, the ValidateSignature middleware for route protection, and an Artisan command to generate the required URL_SIGNER_SIGNATURE_KEY.

Tokens
2.1K
Snippets
12
Records
12
Agent score
71%

What's inside spatie/laravel-url-signer

  1. Protect routes with URL Signer middleware

    main

    You can protect specific routes by applying the ValidateSignature middleware. If a user accesses a protected route with an invalid or expired signature, the application will automatically abort with a 403 Forbidden status code.

    1. Register the middleware Add the middleware to your HTTP Kernel (e.g., in app/Http/Kernel.php):

    protected $routeMiddleware = [
        'signed-url' => \Spatie\\UrlSigner\\Laravel\\Middleware\\ValidateSignature::class,
    ];

    2. Apply to routes Use the middleware alias in your route definitions:

    Route::get('protected-route', fn () => 'Hello secret world!')
        ->middleware('signed-url');
    // in app/Http/Kernel.php
    protected $routeMiddleware = [
        'signed-url' => \Spatie\UrlSigner\Laravel\Middleware\ValidateSignature::class,
    ];
    
    // in routes/web.php
    Route::get('protected-route', fn () => 'Hello secret world!')
        ->middleware('signed-url');
  2. Install spatie/laravel-url-signer

    main

    Install the package via Composer:

    composer require spatie/laravel-url-signer

    After installation, you must set a long secret value in your .env file using the URL_SIGNER_SIGNATURE_KEY environment variable. This key is used to sign and validate all URLs.

  3. Configure the URL Signer

    main

    You can publish the configuration file to customize the signing behavior. The configuration allows you to define the signature key, the default expiration time, and the parameter names used in the generated URLs.

    To publish the config:

    php artisan vendor:publish --tag="url-signer-config"

    Configuration Schema:

    return [
        // The secret string used to generate signatures (from env('URL_SIGNER_SIGNATURE_KEY'))
        'signature_key' => env('URL_SIGNER_SIGNATURE_KEY'),
    
        // The default expiration time of a URL in seconds (default is 1 day)
        'default_expiration_time_in_seconds' => 60 * 60 * 24,
    
        // The parameter names used in the signed URL query string
        'parameters' => [
            'expires' => 'expires',
            'signature' => 'signature',
        ],
    ];
  4. Validate a signed URL

    main

    To check if a URL has a valid signature and has not expired, use the validate() method. It returns true if the URL is valid, and false otherwise.

    use Spatie\UrlSigner\Laravel\Facades\UrlSigner;
    
    $isValid = UrlSigner::validate('https://app.com/protected-route?expires=xxxxxx&signature=xxxxxx');
  5. Sign a URL with a limited lifetime

    main

    Use the UrlSigner facade to create a signed URL. By default, the URL will be valid for one day (as defined in your config). You can provide a custom expiration time using a DateTime instance or a number of seconds.

    Examples:

    Default lifetime (1 day):

    use Spatie\
    UrlSigner\\Laravel\\Facades\\UrlSigner;
    
    UrlSigner::sign('https://myapp.com/protected-route');

    Custom lifetime using DateTime:

    UrlSigner::sign('https://myapp.com/protected-route', now()->addDays(30));
    UrlSigner::sign('https://myapp.com/protected-route', now()->addMinutes(5));

    Custom lifetime using seconds:

    // Valid for 5 minutes
    UrlSigner::sign('https://myapp.com/protected-route', 60 * 5);
    use Spatie\UrlSigner\Laravel\Facades\UrlSigner;
    
    UrlSigner::sign('https://myapp.com/protected-route', now()->addDays(30));
  6. Generate a URL signer signature key

    main

    You can use the provided Artisan command to generate a secure signature key. This command will modify your environment file by default.

    Options:

    • --s|show: Display the generated key in the terminal instead of writing it to your environment file.
    • --always-no: Skip the generation process if a key already exists.
    • --f|force: Overwrite an existing key without asking for confirmation.
    php artisan generate:url-signer-signature-key
  7. Register the UrlSigner singleton in Laravel

    main

    The package registers Spatie\UrlSigner\UrlSigner as a singleton in the Laravel service container. It is aliased to url-signer.

    The singleton is instantiated using values from the url-signer configuration file:

    • signature_key: The secret key used for signing.
    • parameters.expires: The default expiration time for signed URLs.
    • parameters.signature: The name of the signature query parameter.

    You can resolve the signer from the container using either the class name or the alias.

    // Resolving via the class name
    $signer = app(Spatie\UrlSigner\UrlSigner::class);
    
    // Resolving via the alias
    $signer = app('url-signer');
  8. Use the UrlSigner facade

    main

    The UrlSigner facade provides a convenient way to access the UrlSigner service within your Laravel application. It allows you to call methods like sign() and validate() directly through the facade without needing to resolve the service from the container manually.

    use Spatie\UrlSigner\Laravel\Facades\UrlSigner;
    
    // Example usage
    $signedUrl = UrlSigner::sign($url, $expiration);
  9. Sign a URL with UrlSigner::sign()

    main

    The sign method generates a signed version of a URL. You can specify an expiration time and an optional signature key. If no expiration is provided, the method automatically falls back to the value configured in config('url-signer.default_expiration_time_in_seconds').

    $signedUrl = $urlSigner->sign(
        'https://example.com/path', 
        now()->addMinutes(30), 
        'custom-key'
    );
  10. Protect routes with ValidateSignature middleware

    main

    The Spatie\UrlSigner\Laravel\Middleware\ValidateSignature middleware automatically validates that an incoming request contains a valid signature for the URL being accessed.

    If the signature is invalid or missing, the middleware calls handleUnsignedUrl, which by default triggers a 403 Forbidden error using Laravel's abort(403) helper.

    To use this middleware, register it in your app/Http/Kernel.php or apply it directly to specific routes in your routes/web.php or routes/api.php files.

    use Spatie\UrlSigner\Laravel\Middleware\ValidateSignature;
    use Illuminate//Support\Facades\Route;
    
    Route::get('/protected-resource', function () {
        return 'This is a signed URL content';
    })->middleware(ValidateSignature::class);
  11. Generate a new URL signer signature key

    main

    Use the generate:url-signer-signature-key command to generate a new 64-character random string to be used as your URL_SIGNER_SIGNATURE_KEY.

    By default, the command will attempt to write this key directly to your .env file. If the key already exists, the command will prompt you for confirmation before overwriting it, as overwriting the key will invalidate all existing signed URLs.

    Options

    • --s|--show: Display the generated key in the terminal instead of modifying your .env file.
    • --f|--force: Skip the confirmation prompt and overwrite the existing key immediately.
    • --always-no: If a key already exists, skip the generation process entirely without making changes.
    php artisan generate:url-signer-signature-key