soapbox/signed-requests
| Install | |
|---|---|
composer require soapbox/signed-requests |
|
| Latest Version: | v4.2 |
| PHP: | ^8.1 |
| License: | MIT |
| Last Updated: | May 28, 2024 |
| Links: | GitHub · Packagist |
Signed Requests
A wrapper to add the ability to accept signed requests to a Laravel project.
Installation
Composer
composer require soapbox/signed-requests
Setup the Service Provider
Open config/app.php and register the required service provider above your application providers.
'providers' => [
...
SoapBox\SignedRequests\ServiceProvider::class
...
]
Publish the Configuration
php artisan vendor:publish --provider 'SoapBox\SignedRequests\ServiceProvider'
Configuring your Environment
You will need to set the following details in your environment:
SIGNED_REQUEST_ALGORITHM=
SIGNED_REQUEST_CACHE_PREFIX=
SIGNED_REQUEST_SIGNATURE_HEADER=
SIGNED_REQUEST_ALGORITHM_HEADER=
SIGNED_REQUEST_KEY=
SIGNED_REQUEST_ALLOW_REPLAYS=
SIGNED_REQUEST_TOLERANCE_SECONDS=
Each of the settings above allows for a different level of configuration.
SIGNED_REQUEST_ALGORITHMis the algorithm that will be used to generate / verify the signature. This is defaulted to usesha256feel free to change this to anything thathash_hmacaccepts.SIGNED_REQUEST_CACHE_PREFIXis the prefix to use for all the cache keys that will be generated. Here you can use the default if you're not planning on sharing a cache between multiple applications.SIGNED_REQUEST_SIGNATURE_HEADERshould be the request header that the signature will be included on,X-Signaturewill be used by default.SIGNED_REQUEST_ALGORITHM_HEADERshould be the request header that the includes the algorithm used to sign the request.SIGNED_REQUEST_KEYis the shared secret key between the application generating the requests, and the application consuming them. This value should not be publically available.SIGNED_REQUEST_ALLOW_REPLAYSallows you to enable or disable replay attacks. By default replays are disabled.SIGNED_REQUEST_TOLERANCE_SECONDSis the number of seconds that a request will be considered for. This setting allows for some time drift between servers and is only used when replays are disabled.
Setup the Middleware
Signed Requests includes a middleware to validate the signature of a request for your automatically. To get started, add the following middleware to the $routeMiddleware property of your app/Http/Kernel.php file.
'verify-signature' => \SoapBox\SignedRequests\Middlewares\Laravel\VerifySignature::class
Verify the Signature
The verify-signature middleware may be assigned to a route to verify the signature of the incoming request to verify its authenticity:
Route::get('/fire', function () {
return "You'll only see this if the signature of the request is valid!";
})->middleware('verify-signature');
Setting Up Additional Keys
You can also set up additional keys to use if you want different keys for different endpoints.
Add them to your environment:
CUSTOM_SIGNED_REQUEST_ALGORITHM=
CUSTOM_SIGNED_REQUEST_CACHE_PREFIX=
CUSTOM_SIGNED_REQUEST_SIGNATURE_HEADER=
CUSTOM_SIGNED_REQUEST_ALGORITHM_HEADER=
CUSTOM_SIGNED_REQUEST_KEY=
CUSTOM_SIGNED_REQUEST_ALLOW_REPLAYS=
CUSTOM_SIGNED_REQUEST_TOLERANCE_SECONDS=
Update the configuration in signed-requests.php
'default' => [
...
],
'custom' => [
'algorithm' => env('CUSTOM_SIGNED_REQUEST_ALGORITHM', 'sha256'),
'cache-prefix' => env('CUSTOM_SIGNED_REQUEST_CACHE_PREFIX', 'signed-requests'),
'headers' => [
'signature' => env('CUSTOM_SIGNED_REQUEST_SIGNATURE_HEADER', 'X-Signature'),
'algorithm' => env('CUSTOM_SIGNED_REQUEST_ALGORITHM_HEADER', 'X-Signature-Algorithm')
],
'key' => env('CUSTOM_SIGNED_REQUEST_KEY', 'key'),
'request-replay' => [
'allow' => env('CUSTOM_SIGNED_REQUEST_ALLOW_REPLAYS', false),
'tolerance' => env('CUSTOM_SIGNED_REQUEST_TOLERANCE_SECONDS', 30)
]
]
Set up your route to use the custom key. The param you pass must be the same name as the key you set in the configuration in signed-requests.php
Route::get('/fire', function () {
return "You'll only see this if the signature of the request is valid!";
})->middleware('verify-signature:custom');
Signing Postman Requests
If you, like us, like to use postman to share your api internally you can use the following pre-request script to automatically sign your postman requests:
function guid() {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function getTimestamp() {
var date = (new Date()).toISOString();
date = date.split("T");
date[1] = date[1].split(".")[0];
return date.join(' ');
}
postman.setEnvironmentVariable("x-signed-id", guid());
postman.setEnvironmentVariable("x-signed-timestamp", getTimestamp());
postman.setEnvironmentVariable("x-algorithm", "sha256");
var payload = {
"id": postman.getEnvironmentVariable("x-signed-id"),
"method": request.method,
"timestamp": postman.getEnvironmentVariable("x-signed-timestamp"),
"uri": request.url.replace("{{url}}", postman.getEnvironmentVariable("url")),
"content": (Object.keys(request.data).length === 0) ? "" : JSON.stringify(JSON.parse(request.data))
};
var hash = CryptoJS.HmacSHA256(JSON.stringify(payload), postman.getEnvironmentVariable("key"));
var signature = hash.toString();
postman.setEnvironmentVariable("x-signature", signature);
Note for this to work you'll have to setup your environment to have the following variables:
{{url}}this is the base url to the api you'll be hitting.{{key}}this is the shared secret key you'll be using in your environment.
All other environment variables that will be needed will be automatically generated by the above script.
Related Packages
Laravel package that builds dynamic forms in blade and automatically generates v...