masterei / laravel-signer
Laravel signed URL wrapper with additional feature such as consumable and user-based signed URLs.
v1.0.0
2024-04-24 06:15 UTC
Requires
- php: ^8.0
- spatie/url: ^2.4
Requires (Dev)
README
# Laravel Signer [](https://packagist.org/packages/masterei/laravel-signer) [](https://packagist.org/packages/masterei/laravel-signer) Laravel signed URL wrapper with additional feature such as consumable and user-based signed URLs. ## Installation You can install the package via composer: ```bash composer require masterei/laravel-signer ``` You need to publish the migration to create the package table: ```bash php artisan vendor:publish --tag="signer-migration" ``` After that, you need to run migration command. ```bash php artisan migrate ``` Optionally, you can publish the config file with: ```bash php artisan vendor:publish --tag="signer-config" ``` ## Compatibility - Laravel version 9.x.x or later ## Usage ### Basic Usage ```php use App\Models\User; use Masterei\Signer\Signer; // creating signed url that can only be accessed by limited number of times Signer::consumableRoute('subscribe', 1, ['user' => 1]); // expires after a specified amount of time Signer::temporaryConsumableRoute('subscribe', now()->addMinute(), 1, ['user' => 1]); // creating signed url that can only be access by certain specified user/s $user = User::first(); Signer::authenticatedRoute('subscribe', $user, ['user' => 1]); // note: user parameter can accept; user id as int or array, model, collection // expires after a specified amount of time Signer::temporaryAuthenticatedRoute('subscribe', now()->addMinute(), $user, ['user' => 1]); ``` #### Additional Arguments As usual, you may exclude the domain from the signed URL hash by providing the `absolute` argument to the class method. ```php return Signer::consumableRoute('subscribe', 1, ['user' => 1], absolute: false); ``` You may also want to force the domain prefix, even if you excluded the domain from the signed URL hash by providing the `prefixDomain` argument to the class method. ```php return Signer::consumableRoute('subscribe', 1, ['user' => 1], prefixDomain: true); ``` ### Advance Usage ```php return Signer::route('subscribe') // route name ->parameters(['user' => 1]) // additional parameters ->authenticated([1, 2]) // user id as int or array, model, collection ->consumable(2) // number of times url can be accessed ->relative() // exclude domain from signature hashing ->prefixDomain() // force domain prefix on relative url ->expiration(now()->addDays(2)) // url expiration period; accepts: Carbon/Carbon instance ->make(); // finally create the url ``` ### Native Signed URL If you don't want to use the additional feature. Native `signedRoute` and `temporarySignedRoute` is a goto option. Note: This does not store in database and will only be validated using the framework native validation method. ```php Signer::signedRoute('subscribe', ['user' => 1]); // You may exclude the domain from the signed URL hash // by providing the `absolute` argument to the signedRoute method: Signer::signedRoute('subscribe', ['user' => 1], absolute: false); // If you would like to generate a temporary signed URL // that expires after a specified amount of time. Signer::temporarySignedRoute('subscribe', now()->addDay(), ['user' => 1]); ``` ### Validating Signed Route Requests #### Package Signed Route ```php // To ensure that the incoming request has a valid signature, // you have to include the middleware into the route for it to work. Route::post('subscribe/{user}', function (Request $request) { // ... })->name('subscribe')->middleware('signer'); // Sometimes, you want to forcefully disable the framework native validation, // you should provide the `strict` argument to the middleware parameter. Route::post('subscribe/{user}', function (Request $request) { // ... })->name('subscribe')->middleware('signer:strict'); ``` #### Native Signed Route If your route uses the native signed url method namely `signedRoute` and `temporarySignedRoute`; and excluded the domain from the signed URL hash you should provide the `relative` argument to the middleware for it to work. ```php Route::post('subscribe/{user}', function (Request $request) { // ... })->name('subscribe')->middleware('signer:relative'); ``` ## Classes #### Way to reconstruct signed route model back into signed URL: ```php use Masterei\Signer\Models\Signed; return Signed::first()->url(); ``` #### To parse URL and get its underlying data: ```php use Masterei\Signer\URLParser; $parsedUrl = URLParser::fromString(request()->getUri()); return $parsedUrl->getSignature(); ``` #### Finding signed URL model using its signature: ```php use Masterei\Signer\Models\Signed; use Masterei\Signer\URLParser; $parsedUrl = URLParser::fromString(request()->getUri()); return Signed::findValidSignature($parsedUrl->getSignature()); ``` ```php // or specify with path return Signed::findValidSignature($parsedUrl->getSignature(), $parsedUrl->getPath()); ``` ## Changelog Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. ## License The MIT License (MIT). Please see [License File](LICENSE.md) for more information.