Back

Routing with https


Setting url to 'https://www.domain.com' in config/app.php instead of 'http://www.domain.com' seems to have no effect when referring to routes in, say, a form:

Form::open(['route' => 'sessions.store']) will create a <form> tag with action="http://www.domain.com".

Surely this is a bug (although it was rudely dismissed on GitHub). Why else might Laravel insist on http instead of https?

Of course, I would rather use routes than hard-code URLs.

Tested in Laravel 4.2

awsp replied 2 years ago

Don't think this is a bug. Please re-visit the documentation of your config/app.php near url

       /*
	|--------------------------------------------------------------------------
	| Application URL
	|--------------------------------------------------------------------------
	|
	| This URL is used by the console to properly generate URLs when using
	| the Artisan command line tool. You should set this to the root of
	| your application so that it is used when running Artisan tasks.
	|
	*/

        'url' => 'http://localhost',

To do HTTPS, try to make use of route filters.

http://laravel.com/docs/4.2/routing#route-filters

http://stackoverflow.com/questions/19967788/laravel-redirect-all-requests-to-https

PS: If you want your whole site to be HTTPS-protected. Consider the fundamental HTML tag. :D

<base href="https://www.domain.com/" />
tomturton replied 2 years ago

The problem isn't necessarily one of security. It's easy to force SSL server-side, using .htaccess, Laravel filters etc.

It's more a cosmetic thing. If the site uses https:// and there are regular http:// urls on the page, the web browser could show a warning that not everything on the page is secure. In Google Chrome, for example, the green padlock in the address bar appears orange. I don't want this to deter site visitors.

I could use the <base> tag I suppose, but I prefer not to, as I don't like the practice of setting absolute URLs for every page on the site (it can wreck havoc with inline anchors and JS libraries). I also feel this shouldn't be a front-end problem; it is one for Laravel to get right.

I maintain this is a bug; at the very least it is undesirable. The url configuration variable may not be for use outside of Artisan, but I don't like that Laravel assumes http://, especially now, when we are being encouraged to use SSL for everything.

The only workaround I have found is to hardcode my URLs, as opposed to using Laravel routes. This is an issue for two reasons: routes are great for when URLs change, especially when they are used as RESTful resources; also, as I haven't set up an SSL certificate on my development machine, it means I don't have to apply logic or maintain two separate copies of a file to test in both development and production environments.

However, this post is more to promote discussion than find workarounds.

beaverusiv replied 2 years ago

If you look at the code (https://github.com/illuminate/html/blob/master/HtmlBuilder.php)

It does have a $secure parameter. Specifically the code from line 100:

	/**
	 * Generate a HTML link.
	 *
	 * @param  string  $url
	 * @param  string  $title
	 * @param  array   $attributes
	 * @param  bool    $secure
	 * @return string
	 */
	public function link($url, $title = null, $attributes = array(), $secure = null)
	{
		$url = $this->url->to($url, array(), $secure);
		if (is_null($title) || $title === false) $title = $url;
		return '<a href="'.$url.'"'.$this->attributes($attributes).'>'.$this->entities($title).'</a>';
	}

Looks like most if not all HTML elements have it.

awsp replied 2 years ago

Even HTTPS is becoming the standard, I still do not consider the url has done anything wrong.

As written in the documentation, the use of url is for artisan, and artisan is more likely running "local" respected to your server. HTTPS is useful only between the connection of server and client. But again, feel free to change the configuration to https, it is there for you to change.

Now, the issue of HTTPS, unless you are doing iframe, embed, loading JS from external source, (Ex. Facebook likebox, Google API, YouTube's embed videos, etc), the direct use of HTTP should be avoided. The reason causes the yellow lock in Chrome has nothing to do with the <A> tag. It is completely legitimate to have a non-HTTPS hyper link in a HTTPS page, this will not give you a yellow lock.

What gives you yellow lock however, are those, <IMG>, <EMBED>, <SCRIPT>, <IFRAME>, etc. As you already mentioned, it is becoming a standard to have SSL enabled, so it is save for you to use HTTPS on YouTube, Facebook or even Google when you embed their videos and scripts. Just make sure you do not have any HTTP on the above tags in a HTTPS page and you are safe. :D

TLDR; This is from my personal experience tho, whenever you see yellow lock check the source code. 99.9% of the time it is caused by the one of these tags.

By the way, Chrome sometimes does not recognize you have changed the embedding, so it might still give you the yellow lock even you have completely fixed all the HTTPS issue. Try restart your chrome window and green lock will start to appear.

Best of luck

It's more a cosmetic thing. If the site uses https:// and there are regular http:// urls on the page, the web browser could >show a warning that not everything on the page is secure. In Google Chrome, for example, the green padlock in the >address bar appears orange. I don't want this to deter site visitors.

tomturton said:

The problem isn't necessarily one of security. It's easy to force SSL server-side, using .htaccess, Laravel filters etc.

It's more a cosmetic thing. If the site uses https:// and there are regular http:// urls on the page, the web browser could show a warning that not everything on the page is secure. In Google Chrome, for example, the green padlock in the address bar appears orange. I don't want this to deter site visitors.

I could use the <base> tag I suppose, but I prefer not to, as I don't like the practice of setting absolute URLs for every page on the site (it can wreck havoc with inline anchors and JS libraries). I also feel this shouldn't be a front-end problem; it is one for Laravel to get right.

I maintain this is a bug; at the very least it is undesirable. The url configuration variable may not be for use outside of Artisan, but I don't like that Laravel assumes http://, especially now, when we are being encouraged to use SSL for everything.

The only workaround I have found is to hardcode my URLs, as opposed to using Laravel routes. This is an issue for two reasons: routes are great for when URLs change, especially when they are used as RESTful resources; also, as I haven't set up an SSL certificate on my development machine, it means I don't have to apply logic or maintain two separate copies of a file to test in both development and production environments.

However, this post is more to promote discussion than find workarounds.

albertokempis replied 2 years ago

I use this in my filter.php

Route::filter('force.ssl', function()
{
if( ! Request::secure() && App::environment() !== 'local')
{
return Redirect::secure(Request::getRequestUri());
}
});

Route::filter('no.ssl', function()
{
if( Request::secure())
{
return Redirect::to(Request::path(), 302, array(), false);
}
});


Then in your routes.php I use this..

Route::when('admin/*', 'force.ssl');
Route::when('/', 'no.ssl');

tomturton replied 2 years ago

awsp said:

Even HTTPS is becoming the standard, I still do not consider the url has done anything wrong.

As written in the documentation, the use of url is for artisan, and artisan is more likely running "local" respected to your server. HTTPS is useful only between the connection of server and client. But again, feel free to change the configuration to https, it is there for you to change.

Yes, I understand this is the case, as you previously pointed out.

Now, the issue of HTTPS, unless you are doing iframe, embed, loading JS from external source, (Ex. Facebook likebox, Google API, YouTube's embed videos, etc), the direct use of HTTP should be avoided. The reason causes the yellow lock in Chrome has nothing to do with the <A> tag. It is completely legitimate to have a non-HTTPS hyper link in a HTTPS page, this will not give you a yellow lock.

This is interesting and of course very correct. I would not expect to be penalised for linking to other websites that do not use HTTPS.

The particular issue I am having is with <form> tags. A simple example would be creating a login form. Naturally I'd like to secure such a site with HTTPS. Unfortunately, I do see the warning padlock in Chrome when <form action="http://... but not when <form action="https://....

By the way, Chrome sometimes does not recognize you have changed the embedding, so it might still give you the yellow lock even you have completely fixed all the HTTPS issue. Try restart your chrome window and green lock will start to appear.

Best of luck

Thanks for this tip.

The fundamental issue here is that Laravel assumes HTTP. This is a server-side problem, as Laravel generates the URLs.

beaverusiv has noticed that there is a secure parameter in many of Laravel's URL-generating functions, which is a good find, but I can't find the route equivalent and you can't specify that parameter in the Form::open() method. Also, it's not something I expect to have to specify, when referring to internal URLs/routes.

I understand why Laravel URL-generating helpers don't use relative URLs (I think), but if there was a base URL set in the config file, or if Laravel detected the protocol, surely it could serve the correct URLs effortlessly?

I'm surprised this doesn't seem to be a common or serious issue. Any website that stores user data (eg most Laravel sites, I'd imagine) should be using HTTPS, but Laravel makes it difficult/impossible to set a <form> action to a HTTPS URL without hardcoding it in.

Again, I don't expect a solution or workarounds from this thread. It is more to raise awareness of the issue in the hope that a solution can be integrated in future Laravel versions. I tried filing it on the GitHub page, but was directed here.

iWader replied 2 years ago

You can specify if routes should be HTTP or HTTPS by passing ['http' => true] or ['https' => true] as options when declaring your routes, if you don't specify those options then it should just use the same protocol as you're currently accessing the page with.

Route::get('/form', ['uses' => '[email protected]']);
Route::post('/form', ['uses' => '[email protected]', 'https' => true]);

You just have to do a little digging through the laravel/framework repo on github to find many un-documented features

tomturton replied 2 years ago

iWader said:

You can specify if routes should be HTTP or HTTPS by passing ['http' => true] or ['https' => true] as options when declaring your routes, if you don't specify those options then it should just use the same protocol as you're currently accessing the page with.

Route::get('/form', ['uses' => '[email protected]']);
Route::post('/form', ['uses' => '[email protected]', 'https' => true]);

You just have to do a little digging through the laravel/framework repo on github to find many un-documented features

This looks promising, I will have a play when I have some time. It does still seem a shame that the developer has to specify HTTPS for every route associated with the site.

Thanks for this one.

Edit: I've had a look and Laravel doesn't use these options when generating URLs :-( It must be just for forcing SSL once the URLs are accessed.

gabrielverta replied 2 years ago

Looking at the Laravel's source code I found this solution:

URL::forceSchema("https");
tomturton replied 2 years ago

gabrielverta said:

Looking at the Laravel's source code I found this solution:

URL::forceSchema("https");

Bingo! A great workaround. Thank you.

I have also wrapped a conditional statement around this line, so it only applies to my remote configuration:

if (App::environment('remote')) {
    URL::forceSchema('https');
}

Ashamedly, I've just stuck this at the top of my routes file. Anyone know where might a more relevant place be?

cferreiram replied 2 years ago

On Laravel 5, I simply put it on the boot of my AppServiceProvider.

Got a curious problem now. Every Url is generated with https after adding forceSchema. But when using redirect()->intended(), Laravel grabs the url.intended from the Session. This variable is set with http.

And looking to the UrlGenerator::to method, no matter if we set secure to true, it returns the url if is a valid URL before checking for the schema.

How can I make the Session store the urls in https format too ?

youndivian replied 2 years ago

tomturton said:

iWader said:

You can specify if routes should be HTTP or HTTPS by passing ['http' => true] or ['https' => true] as options when declaring your routes, if you don't specify those options then it should just use the same protocol as you're currently accessing the page with.

Route::get('/form', ['uses' => '[email protected]']);
Route::post('/form', ['uses' => '[email protected]', 'https' => true]);

You just have to do a little digging through the laravel/framework repo on github to find many un-documented features

This looks promising, I will have a play when I have some time. It does still seem a shame that the developer has to specify HTTPS for every route associated with the site.

Thanks for this one.

Edit: I've had a look and Laravel doesn't use these options when generating URLs :-( It must be just for forcing SSL once the URLs are accessed.

I am trying 'https' => true with Route::group() but it is not working. I am using L5.1

XaviArnaus replied 1 year ago

This fixed my issue.

route() was creating absolute URLs including the protocol, and with this snippet included at the top of my routes.php started generating https URLs.

This also noticed me I hadn't set up different environment names for my local, preproduction and production ones.

Thank you very much again :)

tomturton said:

gabrielverta said:

Looking at the Laravel's source code I found this solution:

URL::forceSchema("https");

Bingo! A great workaround. Thank you.

I have also wrapped a conditional statement around this line, so it only applies to my remote configuration:

if (App::environment('remote')) { URL::forceSchema('https'); }

Ashamedly, I've just stuck this at the top of my routes file. Anyone know where might a more relevant place be?

GioAbove5K replied 9 months ago

Just to let you guys know, with the newer version of Laravel (5.3)

URL::forceSchema('https');

Works if you add it to the top of your web.php file.

spmoreno replied 9 months ago

GioAbove5K said:

Just to let you guys know, with the newer version of Laravel (5.3)

URL::forceSchema('https');

Works if you add it to the top of your web.php file.

Thanks! That worked for me, Laravel 5.3.

phcco replied 7 months ago

For Laravel 5.4: URL::forceScheme("https");

"forceSchemE", with "E"

  • https://github.com/laravel/framework/commit/39e8c83af778d8086b0b5e8f4f2e21331b015b39
phpScots replied 6 months ago

Here is simple example of reverse routing in laravel https://laravel-interview-questions.blogspot.in/2017/03/what-is-reverse-routing-in-laravel.html


Sign in to participate in this thread!



We'd like to thank these amazing companies for supporting us