Reputation:
I'm using asset()
public method to generate correct url in laravel.
in docs it says:
So in theory it should detect correct scheme itself.
But in code I see: https://github.com/illuminate/routing/blob/master/UrlGenerator.php#L210
public function asset($path, $secure = null)
{
default for secure is null. So this method is no good for both http/https.
what am I missing here?
I'm using reverse proxy, could it because of that?
Upvotes: 9
Views: 9827
Reputation: 1476
Please stop writing code for doing things that already exist. There is a ASSET_URL env variable. Use it.
ASSET_URL=https://your.app.url #in env for production
ASSET_URL=http://your.app.url #in env for local development
( https://stackoverflow.com/a/68287406/7481663 )
Upvotes: 7
Reputation: 195
I was doing some maintenance in some legacy systems built in Laravel 4.2 and stumbled in this situation.
After giving a look at how the Generators are instantiated and used, I solved the problem setting the UrlGenerator
forcedSchema
property after the environment detection at the start.php
file of the application.
// The if condition depends on what identifies your https host
if( str_contains($_SERVER['HTTP_HOST'], 'secure_app_host_fragment')){
$app['url']->forceSchema('https');
}
Upvotes: 0
Reputation: 2562
Yes, that happens because the reverse proxy will do SSL termination, which means that the browser requests https, but the request that goes from the proxy to the app is http. This has many benefits (improved performance) but it does have this side-effect.
I think the solution would go as an environment variable that tells you to force https (when using the web on staging or production) or to leave as http when e.g. developing locally.
I think is the most effective. I say this because your app will never know when to use https or not.
Upvotes: 2
Reputation: 301
In case anyone falls into this same issue like I did in order to allow the asset
function to get the proper schema you would have to enable TrustedProxies
.
In laravel there is a middleware that does that for you in \App\Http\Middleware\TrustedProxies
but you must included it in your default middleware before it can take effect.
Laravel uses the fideloper/TrustedProxy
package which sets the trustedProxies
array in the Request
object which is checked in order to approve the X-Forwarded-Proto
provided in the header.
You can check the following link to get more details
Explains in Laravel Trusted Proxy in details
Upvotes: 1
Reputation: 27190
As you can see from GitHub the asset
method is calling getScheme
to determine what the scheme should be.
https://github.com/illuminate/routing/blob/master/UrlGenerator.php#L303
public function formatScheme($secure = null)
{
if (! is_null($secure)) {
return $secure ? 'https://' : 'http://';
}
if (is_null($this->cachedScheme)) {
$this->cachedScheme = $this->forceScheme ?: $this->request->getScheme().'://';
}
return $this->cachedScheme;
}
So if you don't provide the asset
2nd parameter $secure
then it uses the request scheme. Otherwise you can provide $secure
to force the desired scheme regardless of what is the scheme in the request.
If you look at the code you'll see that if $secure
is null and no cache is set than the cache is set to the request scheme (i.e. $this->request->getScheme()
) and therefore returned.
Upvotes: 3
Reputation: 2037
On the very same file, you have a definition of the getScheme() method, which uses the $secure parameter.
If the $secure parameter is the default null
value, the scheme is either guessed from the current scheme, or retrieved from the previous saved scheme (If it hasn't been forced with forceSchema()).
You could tell the $secure parameter works that way :
true
will force httpsfalse
will force httpnull
will use the best scheme, guessed from the current schemeHere's the code from the getScheme() method :
protected function getScheme($secure)
{
if (is_null($secure)) {
if (is_null($this->cachedSchema)) {
$this->cachedSchema = $this->forceSchema ?: $this->request->getScheme().'://';
}
return $this->cachedSchema;
}
return $secure ? 'https://' : 'http://';
}
Upvotes: 1
Reputation: 13640
isn't it secure_asset
you're looking for?
https://laravel.com/docs/5.3/helpers#method-secure-asset
Upvotes: 3