Playing
01. Forcing HTTPS assets with Laravel

Episodes

0%
Your progress
  • Total: 8m
  • Played: 0m
  • Remaining: 8m
Join or sign in to track your progress

Transcript

00:00
In this snippet, I'm going to talk to you about a problem that I see quite often and it's a question I get asked and that is issues with HTTPS when you're pushing a Laravel project up to some kind of platform, whether that's just self-hosted or something like Heroku which we're going to be using in this to demonstrate it.
00:19
Now I've already pushed this up to Heroku. We'll take a look around the setup just if you are using Heroku. But you'll see here when I go ahead and click on Login, we're actually being transferred over to use the HTTP schema, not HTTPS.
00:32
Now if I go ahead and switch this over to HTTPS, you see we get the following issue. Now the reason for this, if we just bring up the console, is what's happening is if we just view the page source here, the schema builder within Laravel or the asset builder within Laravel is using the HTTP scheme and not the HTTPS scheme.
00:53
Now I won't dive into why this happens because it depends on the platform. What we are going to do though is look at two solutions to get around this. One is a little bit more flexible than the other. So even if you've not had this problem, it's a good idea to follow this through just so
01:07
you know how to deal with this in future. Okay. So let's take a look at the app I have set up here. All I've done is gone ahead and installed Laravel 5.5, it doesn't matter which version
01:16
of Laravel you're working with, and I've gone ahead and pushed this up to Heroku and I'm currently running on Apache. Now I've pushed up some configuration variables that are required. So these are just in our environment.
01:26
We have an appenv set to production, we have the app key, the app name, and I've set the app URL to the HTTPS version of the actual page that we're on or the domain that we're working on. So the problem here then is, like I said, with the asset builder, if we just take a
01:42
little dive into this first of all, so if we go ahead and open up the helpers within Laravel and we go down to find the asset function, you can see that this is using the URL generator. So let's go ahead and open this up first of all, just so we can take a look inside of here.
01:58
So what we're doing in here then, we just go back to our helpers, is we're using the asset function. So let's take a look at this. And you can see here that it's using the format scheme method.
02:06
So once again, we can go ahead and open this. And if you take a look here, we do have a secure option. So you can actually use the secure asset method, but of course, that's not going to work on your local machine.
02:16
So you could use secure asset everywhere to generate something with an HTTPS scheme. But in this case, it's not very practical because we need HTTP usually for development. So you can see here that we have a cached schema, and we can actually force the scheme. And this will use that scheme.
02:31
Otherwise, what it's going to do is it's going to hit Laravel's request object, or in this case, Symfony's request object, and it's going to use get scheme. And that's where the trouble comes with different platforms. So what we really want to do here to make this work is basically force the scheme.
02:45
But of course, we need to handle this between different environments. Now I've just opened this up on my local machine. And if I hit log in, of course, this is working, isn't secure because we're just locally developing. But we can go ahead and see that this is working as normal.
02:58
Now what we need to do is fix this up so it works locally and in production. So what I tend to do is create a new service provider for this, but you can do this inside of the boot method of your app service provider if you want. So let's dive into the two solutions.
03:14
The first one, since we've already pushed this up to Heroku with the appenv set to production, is check if we're on a production machine and then go ahead and force that scheme. So in this case, we could use an if statement in here and we could say app, and let's just backslash that, environment.
03:31
And we can check if we just spell environment properly. If we're on production, like so, then in this case, we want to go ahead and force that scheme. The question is, how do we do that? Well, inside of a service provider, we can go ahead and inject in the URL generator,
03:47
much like we can inject anything in. So let's go ahead and pull the namespace in for this just at the top. So this is illuminate routing URL generator, but we want to pull the contract in rather than the actual concrete implementation.
03:59
So what we can do now is if we go ahead and open up the URL generator, we actually have a force scheme. If we open the right one up, so let's look for the Laravel one just here. So we have a force scheme method, and that's going to go ahead and set that property.
04:13
And then subsequently, the asset generator will go ahead and use that scheme. So let's go ahead and do this. And in here, we just want to say URL force scheme, and we want to use, of course, HTTPS. So if we're in a production environment, we're always going to use HTTPS.
04:30
Now this isn't the most flexible solution. I'm going to go ahead and push this up to Heroku. So let's go ahead and add our changes, go ahead and commit these. So we'll just say force HTTPS, go ahead and push these up to Heroku, and let's check this
04:43
out. Okay. So that's been pushed up to Heroku. If we go over to this page now and give that a refresh, you'll notice once this has finished
04:50
that this now works. Because we're in that production environment, the asset builder for the URLs of our assets are in fact using the correct scheme because we've gone ahead and forced that. Now like I said, this isn't the most flexible solution because you might have some other
05:06
app in production that maybe you don't want to necessarily use HTTPS for, or you might have some kind of staging server or some other server that you want to not force for. So in this case, we'd have to do lots of checking here to check if this then do that, if this do that, and we don't really want to kind of mess around with that.
05:25
So the next solution is to actually use an environment variable for this. So what I would usually do on any projects I create is I would have a force HTTP environment variable. Now if that's the case, we can go ahead and use force scheme once again to force that
05:41
to HTTPS. But of course, we need to add this to our server. So let's go ahead and push the changes up to this very quickly. And let's go and use the same commit message and go ahead and push this to Heroku and check
05:52
this out. Okay. So that's deployed again. If we come over now and give this a refresh, of course, because we've switched that over,
05:58
you'll see this no longer works. But what we can now do is whichever server that we're working on, we can use force HTTPS, set that explicitly to true, go ahead and add that, and that should go ahead and work. You can do this from the command line as well.
06:12
If you are working with Heroku, you can use Heroku config add, and then you would just say force HTTP true, just like we've just done over in the web interface. So now when we go ahead and refresh this, if we wait for that to finish, and it looks like I've actually called that force HTTP, but you kind of get the idea.
06:30
Let's just switch the name of this over. So let's get rid of this and add this back in. So you would, of course, say force HTTPS, not force HTTP. Let's add this in, and once that's rebooted, we should see this working as we want.
06:46
And there we go. It works exactly the same way. So of course, you're going to want to go ahead and use force HTTPS, not force HTTP. But that is pretty much it.
06:55
And this is the solution I actually use. It just gives me a little bit more control over doing this. So now when you deploy your application to perhaps another platform or another server, you know that you don't have to worry about your environment variables in terms of the
07:09
if we just go ahead over to EMV, the EMV just here, you can go ahead and just include this and that will force HTTPS for you. Now what I'd recommend you do is place this in some kind of configuration. So if we just come over to config and app, maybe you just had some kind of property here
07:27
that went ahead and referenced that. So force HTTPS, and that would, of course, use EMV. And we would have force HTTPS on there. And then by default, we would have that as false.
07:38
So you can go ahead and add that in and then reference that using your config helper, which would be the following. So config, and that would be app force HTTPS, but I'm going to assume you know how to do that.
07:50
So there we go. Just a really quick solution to going ahead and making sure that your assets are rendered properly so you don't see any warnings about content being served from a non-secure location when you are, in fact, using a certificate.
1 episode 8 mins

Overview

A common problem when using HTTPS with Laravel is JavaScript and CSS assets breaking. In this snippet, we'll discuss a quick solution to fix that.

Alex Garrett-Smith
Alex Garrett-Smith
Hey, I'm the founder of Codecourse!

Episode discussion

No comments, yet. Be the first!