SSL

I would like certain pages in my application to use SSL. What is the standard method to switch to SSL?

I usually use something along the lines of:




if(!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') {

   header('Location: https://' . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']);

   exit;

}



Instead of doing the header() call, you can use the Yii redirect function.

I took a look at CHtml::link() and there is nothing in that to specify an SSL parameter. This is a stark oversight in my opinion.

Oh, I see what you are saying. I was totally out in left field with my response compared to what you were looking for. I will have a look into the link stuff in more detail and see if I can come up with anything. You may consider putting in a feature request for the https thing, though.

I just did an SSL test with Yii. If I make a request using SSL, eg. https://localhost/myapp/index.php, then every link (CHtml::link()) on the page becomes an SSL link!!

This is definitely not the kind of behavior any application needs and IMO is a disastrous bug. Now I need to find out how to remove this behavior :unsure:

There it is straight from the horse’s mouth.

Now, lets give this a little bit of thought. Very few web applications will run entirely on HTTPS, yet many do require that some pages, eg. registration, user pages, e-commerce checkout pages DO run HTTPS while the remainder of the application runs HTTP. To run an application entirely HTTPS is a massive performance hit and just nonsensical.

Clearly, the way that Yii handles URLs requires a rewrite to include an optional $request_type parameter while defaulting to HTTP. The way things are now, once an HTTPS request is made, the whole application is then locked into HTTPS. That is just plain ridiculous!

Without this change, one may as well find another framework, since the time involved with hand coding every single link in an application defeats the whole purpose of using it in the first place.

CHtml::link() generates relative links if provided with a route. So all these links will use the same schema anyway. If you need some links to use another schema, create their URL manually with Yii::app()->createAbsoluteUrl(). You can specify the desired schema there.

Yes, createAbsoluteUrl() can be used for creating HTTPS links, GREAT! But the problem is:

If the application defaults to whatever the current request is, as it does with the Chtml::link() function (which is the application default), then the application will be LOCKED into SSL mode as soon as a HTTPS request is made, because all links will then be HTTPS and there is no escape. This is extremely undesirable behavior for any application. As far as I am concerned it is a bug.

If we are to rely on Chtml::link() as it is, then all links generated by Yiic would need to be manually changed to createAbsoluteUrl(). Now, lets think logically about development time if nothing else.

The only valid solution is to make core changes as to how Yii generates it’s default links using Chtml::link(). HTTPS should never be inherited from the request (unless perhaps we also have a global setting for apps required to run entirely HTTPS).

Well, launchpad.net runs entirely in HTTPS and I don’t have any problems with it. It’s just a design issue. If a site supports SSL there is no reason why the links shouldn’t continue to be https. If I go to a web page and for it to https I want it to stay that way, not to switch to HTTP because the links are hardcoded to http. THAT would be a major bug in my opinion.

If you are redirecting to a login page, etc, which needs to run with HTTPS, usually the method is make the action of the form submit to an https page that then redirects to a normal http page afterwards. In my opinion, the way Yii works is what 95% of developers what and what 98% of users want. There are a few situations where it doesn’t make sense - from the perspective with which you are approaching it, but those are not the only situations.

And, honestly, hand coding the urls takes as much time as using CHtml::link(). And, if you are worried about performance, then you shouldn’t be using the framework HTML helpers to begin with. Because they go through and do a bunch of static function calls. From a PHP perspective, object function calls take a long time. Chances are you aren’t doing enough of them on any given page to make that much of a difference, but when you have 1000 people hitting your website simultaneously, all of those little function calls will add up. (Caching also comes in useful at that point as well).

Like I said before, if I change the url manually to https, I want it to stick that way (from a user perspective). If you have a specific page that needs SSL (that does some sort of encrypted form post) and you don’t want the rest of the application to be in https, then it is your job as a programmer to process the data then redirect to a normal http page.

If you wanna add your own child class of CHtml (I know I have my own helper class that I use for special functionality), then feel free to make your own implementation of CHtml::link that has this other option. It shouldn’t be too hard to implement.

Well gee, I am on my bank’s login page which quite naturally is an SSL page. Yet all the regular links on the page remain HTTP, as they should. For what reason, for example, would the link to the HOME page change to HTTPS, since there is nothing on that page that requires SSL? No reason whatsoever, which is why the link remains HTTP as it should.

Now, how do you suggest that the following should be handled? If I am on my account page, which is SSL, and wish to click on the "Home" link, then according to you the home page must be coded to detect that the request was SSL and then redirect to non-SSL? Is this REALLY how an application should be?? Do you not see that defaulting all links to the SSL request type is the wrong way for an application to behave?

You are suggesting that the design of Yii in this respect is correct and that developers must throw around a whole bunch of redirects within their code to change the mode under which the application is running! I think not <_<

I would not rely on links pointing to a https url. If you want a page to use ssl the page should only be useable with ssl. So in my opinion that is not a matter of links and their link pointing to a ssl page. The page itself should handle it.

No, that is not what I was saying. I was saying, for example, if you have a login page and you want it to be SSL then once the login functionality it done your login page should redirect back to a non-SSL page. I was not saying you needed code inside your application to redirect to non-SSL if you didn’t want it.

If I was on your bank’s website and I manually change the url to https:// because I wanted to browse securely, I would be very irritated if every time I clicked a link it took me back to an http:// page. Yeah, so there’s not any content that needs to be encrypted on the page, but that doesn’t mean I don’t want to browse on an encrypted connection anyway.

Running a website over HTTPS has little to no real performance effect on the server. The logic that it is a bug to display pages that don’t need to be encrypted over and encrypted connection is a bug is just a perspective issue.

If I am creating a relative URL, then I would expect it to continue using whatever protocol the current URL is using, even if that protocol was Gopher://. If I wanted to force a link to a given protocol then I would expect to make an absolute URL to whatever page I wanted to have in that protocol.

And that is the methodology that Yii is working on, and every framework I have worked with that has link generators has this same methodology when it comes to relative URLs.

If you don’t like it, it shouldn’t be that hard to write your own helper that extends CHtml and either create the method you want or add the optional arguments to the methods that already exist.

It’s not just the framework your fighting but the browser as well. On relative urls the browser will take the tld and combine it with the relative url to get the full url to make it’s request. You have to provide an absolute url to prevent the browser from doing it’s translation.

For my login stuff i use ajax and send the data through https from http. It’s more complex than it should because http->https is cross site scripting but at least the data is encrypted. If the login succeeds then they are redirected to an http page with them logged in.