问题
I've setup two routes
Route::get('/bugreport', 'SomeController@create')
->middleware('signed')
->name('bugreport');
Route::get('/getlink', function() {
return dd(\URL::signedRoute('bugreport', ['data' => 3]));
});
When APP_ENV=local
I can visit /getlink
then hit the resulting url and have it show. When APP_ENV=production
(the actual physical environment has not changed when changing the variable) this no longer works... stating invalid signature. Any suggestions?
UPDATE:
We do have... which might be part of it
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
if (!config('app.is_local')) {
URL::forceScheme('https');
}
}
Note: removing the above code actually does fix this issue, but then it breaks e.g. login... so either need to understand why, or this isn't an option :(.
Update Update:
The environment is heroku and the .htaccess has (as per https://help.heroku.com/J2R1S4T8/can-heroku-force-an-application-to-use-ssl-tls)
#### FORCE SSL
## see - https://help.heroku.com/J2R1S4T8/can-heroku-force-an-application-to-use-ssl-tls
RewriteCond %{HTTP_HOST} !=localhost
# If we receive a forwarded http request from a proxy...
RewriteCond %{HTTP:X-Forwarded-Proto} =http [OR]
# ...or just a plain old http request directly from the client
RewriteCond %{HTTP:X-Forwarded-Proto} =""
RewriteCond %{HTTPS} !=on
# Redirect to https version
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
### End Force SSL
回答1:
I had a similar problem - it can be solved very easy if you use the TrustedProxy Middleware.
If you are on Heroku or AWS behind Load Balancers, and you have SSL offloaded to load balancers, you might want to Trust all proxies, so that Laravel's Request can detect that you are actually on a SSL connection. Then Signed URL Validation will work.
You can see the doku here:
Laravel 5.7 https://laravel.com/docs/5.7/requests#configuring-trusted-proxies
Laravel 5.6 https://laravel.com/docs/5.6/requests#configuring-trusted-proxies
回答2:
Update: Use the accepted answer instead.
I finally isolated this down to the Heroku changing the protocol on the requests, so that even when the client makes a request in https
laravel will always receive it as http
in the request object. The workaround was
if (!config('app.is_local') && strpos($request->url(), 'http:') !== false)
{
$url = str_replace('http:', 'https:', $request->fullUrl());
$request = Request::create($url);
}
if (!$request->hasValidSignature()) {
return abort(403);
}
This was sufficient for my needs.
来源:https://stackoverflow.com/questions/52866689/laravel-5-6-signed-url-wont-work-in-app-env-production