Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

jmurphy1267's avatar

Files with an API

I have an API that I need to provide a URL to download files, and the API has to have some form of authentication. I was originally thinking of using a signed URL for this task but I am unable to get that to work. When I go to the URL all it does is return a 403 error. For example, my API URL is api.website.com and the frontend is hosted on a different URL. What would be the best way to serve up those files while having authentication?

0 likes
11 replies
mabdullahsari's avatar

2 options:

  • Place the route outside the boundaries of the auth middleware
  • Add withoutMiddleware('auth') to your route definition

The entire purpose of a signed URL is to give complete ownership to those who got a hold of it for a certain amount of time.

1 like
Tippin's avatar

@jmurphy1267 A signed URL will work perfectly fine if as stated above, you place it outside of any "auth" middleware, maybe even in your "web" routes, or, a whole different route group that is not in web or API, as you do not need sessions or authentication to be processed when handing out signed URLs.

1 like
jmurphy1267's avatar

@Tippin I do have it outside of the auth middleware. My intention was to use signed URLs as a way to keep files secure. I am still getting a 403 after my front end gets the URL from the request and goes to the URL.

Tippin's avatar

@jmurphy1267 Have to ask the obvious question...your routes are not cached right? If you do a php artisan route:list can you confirm your signed route shows up lacking the "auth" middleware? Well, technically 403 sounds more like invalid signature or a policy blocking it, as auth would throw 401

jmurphy1267's avatar

@Tippin I can confirm that it is a signature problem when i go to the document url the error that i get is 403 INVALID SIGNATURE.

Tippin's avatar

@jmurphy1267 Mind showing how you generate the route? Are you just using the single signed middleware on that route/controller? If it is coming up with a bad signature, then could be you are using a temporary signed URL with invalid / too-short of an expiration, or somehow extra characters / modifications are being made to the route possibly?

jmurphy1267's avatar

@Tippin Route in web routes right now getting the same message no matter what route file.

Route::get('pdf/{pdf}',[\App\Http\Controllers\Api\V1\PDF\InvoicePdfController::class, 'invoice'])->name('pdf');

In the controller for pdf download i have this in my constructor:

public function __construct(){ $this->middleware('signed'); }

In the api resource i have 'path' => URL::signedRoute('pdf',['pdf' => $this->getKey()])

Tippin's avatar

@jmurphy1267 Hmm, nothing seems out of place to my eyes. I assume $this->getKey() is you using the models key as the routing identifier. Can you ensure the pdf key is not generating as null? Also, when your UI attempts to fetch the URL, can you confirm NO extra parameters are being tacked onto the URL after the fact? I assume your generated route should look exactly similar to:

http://yoursite.test/pdf/123456?signature=b2fadab63e26223623396dac944feac37d4c57e541e581a85cea27490fa86b3f

and NOTHING else attached/tacked on.

mabdullahsari's avatar

@jmurphy1267 Sorry, should've caught right off the bat it was a 403 and not a 401. Ahh, HTTP status codes...

Make sure the URL is pristine and not tampered with, just like @tippin pointed out.

Please or to participate in this conversation.