laravel url signer

Create and validate signed URLs with a limited lifetime

709
50
PHP

Create signed URLs with a limited lifetime in Laravel

Latest Version on Packagist
Build Status
Quality Score
Total Downloads

This package can create URLs with a limited lifetime. This is done by adding an expiration date and a signature to the URL.

The difference with Laravel’s native route signing is that using this package:

  • you can easily use signed URLs between different apps
  • the signing secret used is not tied to the app key
  • you can easily sign any URL (and not only a route belonging to your app)

This is how you can create signed URL that’s valid for 30 days:

use Spatie\UrlSigner\Laravel\Facades\UrlSigner;

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

The output will look like this:

https://app.com/protected-route?expires=xxxxxx&signature=xxxxxx

The URL can be validated with the validate-function.

// returns `true` if the signed URL is valid, `false` if not
UrlSigner::validate('https://app.com/protected-route?expires=xxxxxx&signature=xxxxxx');

The package also provides a middleware to protect routes.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You’ll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Installation

As you would have guessed the package can be installed via composer:

composer require spatie/laravel-url-signer

You must set an environment variable called URL_SIGNER_SIGNATURE_KEY and set it to a long secret value. This value will be used to sign and validate signed URLs.

php artisan generate:url-signer-signature-key
        {--s|show : Display the key instead of modifying files.}
        {--always-no : Skip generating key if it already exists.}
        {--f|force : Skip confirmation when overwriting an existing key.}

The configuration file can optionally be published via:

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

This is the content of the file:

return [
    /*
    * This string is used the to generate a signature. You should
    * keep this value secret.
    */
    'signature_key' => env('URL_SIGNER_SIGNATURE_KEY'),

    /*
     * The default expiration time of a URL in seconds.
     */
    'default_expiration_time_in_seconds' => 60 * 60 * 24,

    /*
     * These strings are used a parameter names in a signed url.
     */
    'parameters' => [
        'expires' => 'expires',
        'signature' => 'signature',
    ],
];

Usage

URL’s can be signed with the sign-method:

use Spatie\UrlSigner\Laravel\Facades\UrlSigner;

UrlSigner::sign('https://myapp.com/protected-route');

By default, the lifetime of an URL is one day. This value can be change in the config file.
If you want a custom lifetime, you can specify the number of days the URL should be valid:

use Spatie\UrlSigner\Laravel\Facades\UrlSigner;

// the generated URL will be valid for 5 minutes.
UrlSigner::sign('https://myapp.com/protected-route', now()->addMinutes(5));

// alternatively you could also pass the amount of seconds
UrlSigner::sign('https://myapp.com/protected-route', 60 * 5);

Validating URLs

To validate a signed URL, simply call the validate()-method. This method returns a boolean.

use Spatie\UrlSigner\Laravel\Facades\UrlSigner;

UrlSigner::validate('https://app.com/protected-route?expires=xxxxxx&signature=xxxxxx');

Protecting routes with middleware

The package provides a middleware to protect routes.

To use it you must first register the Spatie\UrlSigner\Laravel\Middleware\ValidateSignature as route middleware in your HTTP kernel.

// in app/Http/Kernel.php

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

Next, you can apply it on any route you want.

Route::get('protected-route', fn () => 'Hello secret world!')
    ->middleware('signed-url');

Your app will abort with a 403 status code if the route is called without a valid signature.

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

You can run the test using this command:

composer test

Usage outside Laravel

If you’re working on a non-Laravel project, you can use the framework agnostic version.

Contributing

Please see CONTRIBUTING for details.

Security

If you’ve found a bug regarding security please mail [email protected] instead of using the issue tracker.

Postcardware

You’re free to use this package, but if it makes it to your production environment we highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using.

Our address is: Spatie, Kruikstraat 22, 2018 Antwerp, Belgium.

We publish all received postcards on our company website.

Credits

License

The MIT License (MIT). Please see License File for more information.