How to Back Up a Laravel Application with Spatie Laravel Backup
A Laravel service needs its database and runtime files, including user uploads. A backup gives you copies to restore after data loss…
When someone uses a link to access a Laravel route, Laravel uses the signed URL to check whether anyone changed the URL or its query parameters, the values after ? in the address. An expiring signed URL adds a deadline: Laravel rejects the link after its expiration time.
Use URL::temporarySignedRoute() to create the link and Laravel’s signed route middleware to validate it. The signature shows whether someone changed the URL. It does not identify the person using the link or replace authorization checks for sensitive files and records.
Give the route a name, then pass that name, an expiration time, and any route parameters to temporarySignedRoute:
use Illuminate\Support\Facades\URL;
$url = URL::temporarySignedRoute(
'files.download',
now()->addMinutes(30),
['file' => $file->getKey()]
);
files.download names the route, and file supplies the value for its {file} parameter. now()->addMinutes(30) sets the expiration. Laravel adds the expiration time and signature to the URL, and the recipient can use the link until it expires.
For example, define the route like this:
use App\Http\Controllers\DownloadFileController;
use Illuminate\Support\Facades\Route;
Route::get('/files/{file}/download', DownloadFileController::class)
->middleware('signed')
->name('files.download');
Laravel’s URL generator provides temporarySignedRoute for creating expiring links, along with methods for checking signatures and expiration. The signed middleware checks the incoming URL before the route handler runs. If the signature is invalid or the link has expired, Laravel rejects the request, typically with a 403 response.
Laravel signs the generated URL using the application key, the secret key configured for the project. For each request, Laravel checks the URL and its query parameters against the signature. For a temporary link, it also checks whether the expiration time has passed. If someone changes a parameter or appends a query parameter after signing, the signature no longer matches. A reported Laravel email-verification issue shows validation failing after someone added an extra query parameter.
Include every value the recipient needs among the route parameters when you create the URL. For example, include a file identifier before signing rather than appending a return parameter afterward. The query string remains visible to anyone who receives the link, so do not put passwords or other secrets in it.
A valid signature also does not prove that the person opening the link owns the file. In the controller, use your normal authentication or authorization rules when the resource requires them. Treat a signed URL as permission to use a specific link until its deadline, not as proof of identity.
The most common causes are a changed URL, a mismatch between the URL Laravel generated and the URL it sees on the request, or an application-key change. For standard absolute signed URLs, Laravel checks the URL’s host and scheme, the part that says http or https, as part of the signature. If a proxy server, which forwards requests to Laravel, ends the HTTPS connection and forwards the request as HTTP, Laravel can reject the signature. A Laravel report describes this kind of scheme mismatch.
When a valid link returns 403, compare the received URL with the generated one. Check the host in each URL, then compare their protocols (http or https). Compare the query strings too. If the request passes through a proxy, configure Laravel to trust the relevant proxy headers so it can determine the original scheme. Also check whether the application key changed after the link was created. Laravel 13 checks signatures against the current key and configured previous keys. Links signed with an old key fail if Laravel no longer has that key.
Keep APP_KEY configured. If you rotate it in Laravel 13, keep the old key in APP_PREVIOUS_KEYS while outstanding links must remain valid. OWASP’s Laravel security guidance also recommends disabling debug mode in production with APP_DEBUG=false, which helps prevent detailed error information from reaching users.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com