11

I have a site that has some strict requirements for SEO purposes.

The main one is redirecting all http requests to https which I have done by adding this into the AppController:

public function forceSSL() {
    return $this->redirect('https://' . env('SERVER_NAME') . $this->here);
}

public function beforeFilter() {
    $this->Security->blackHoleCallback = 'forceSSL';
    $this->Security->requireSecure();
}

The issue I have is with 404 pages, they do not redirect to https (eg. www.hublink.net/asdfg)

I have also added these 2 lines to the .htaccess file (from another post), and removed the above code but then get a "redirect loop" error

RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
halfer
  • 18,701
  • 13
  • 79
  • 158
djcamo
  • 237
  • 2
  • 3
  • 10

6 Answers6

19
RewriteEngine On
# This will enable the Rewrite capabilities

RewriteCond %{HTTPS} !=on
# This checks to make sure the connection is not already HTTPS

RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R=301,L]
# This rule will redirect users from their original location, to the same location but using HTTPS.
# i.e.  http://www.example.com/foo/ to https://www.example.com/foo/
# The leading slash is made optional so that this will work either in httpd.conf
# or .htaccess context

See https://wiki.apache.org/httpd/RewriteHTTPToHTTPS It worked for me.

Fred Noriega
  • 329
  • 2
  • 7
9

I have this in my .htaccess file and it works great. I have it ignoring local and staging URLs, like if I had http://local.example.com it will not force redirection for that url. Those lines can be removed. I like using the .htaccess approach over the one in the AppController. This is also the top level .htaccess file in a standard CakePHP install on a shared hosting environment. There are three .htaccess files in a normal Cakephp install.

<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /

    # FORCE SSL REDIRECTION
    RewriteCond %{ENV:HTTPS} !on [NC]
    RewriteCond %{HTTP_HOST} !^local [NC]
    RewriteCond %{HTTP_HOST} !^staging [NC]
    RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

    RewriteRule ^$ app/webroot/ [L]
    RewriteRule (.*) app/webroot/$1 [L]
</IfModule>

Check your hosting environment and make sure your allowed to have .htaccess files. Need to make sure ModRewrite is installed and working as well.

darensipes
  • 674
  • 6
  • 9
5

So I couldn't find a good way to force my entire site to https without getting redirect loops and errors. This will work on a page level as well if you modify the individual controller for that page). anyway, this is what I finally did after messing with this for a couple of days.

Inside my controllers folder in the AppController.php I placed the following code directly under:

public function beforeFilter() {

=================================

 // Force to SSL
 $this->request->addDetector('ssl', array(
    'env' => 'HTTP_X_FORWARDED_PROTO',
    'value' => 'https'
));
if($_SERVER['HTTP_X_FORWARDED_PROTO'] == "http") {  return $this->redirect('https://' . env('SERVER_NAME') . $this->here); }

So what this does is first check for whether it's http or https. If it's http, then I redirect the page to it's https version. By putting it in the AppController.php controller ... this will secure the entire site.

Hope this helps someone else who is also struggling.

ChrisO
  • 51
  • 1
  • 1
4

The Last Method was for CakePHP2. The following is updated slightly for CakePHP3:

Inside my controllers folder in the AppController.php do the following:

1.******** Add In The Initialize Function *********


public function initialize()
{
    parent::initialize();

    /* ADD THIS NEW LINE */
    $this->loadComponent('Security', ['blackHoleCallback' => 'forceSSL']); // SSL SECURITY
  1. ************ Add A New Public Function **********


    public function forceSSL()
    {
     return $this->redirect('https://' . env('SERVER_NAME') . $this->request->here);
    }
    

3.**** Add this in the beforeFilter function ******


public function beforeFilter(Event $event)
{

    /* ADD 2 NEW LINES */
    parent::beforeFilter($event); 
    $this->Security->requireSecure();
Chris O
  • 41
  • 1
1

If you see #SERVER-HTTPS-ON# (on), add

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

If you see #SERVER-HTTPS-ON# (1), add

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTPS} !=1
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

If you see #SERVERPORT443#, add

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{SERVER_PORT} !443
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

If you see #LOADBALANCER#, add

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

If you see #CDN#, add

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:X-Forwarded-SSL} !on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

If you see #Cloudflare#, add

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP:CF-Visitor} ‘”scheme”:”http”‘
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

If you see #ENVHTTPS#, add

<IfModule mod_rewrite.c>
RewriteEngine on   RewriteCond %{ENV:HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>

On the bottom of the ssl test page, you will see HTTP HOST. This should be the same as your domain. If not, you might need to hardcode your domain to prevent redirect issues, like this:

RewriteEngine on
RewriteCond %{HTTPS} !=on [NC]
RewriteRule ^(.*)$ full_url_with_https/$1 [R=301,L]

more info here

Kamal Kumar
  • 2,495
  • 1
  • 16
  • 15
1

in Controller/AppController.php
This code is working for my CakePHP 3.8

use Cake\Routing\Router;

and

public function initialize()
    {
        parent::initialize();
        if(env('REQUEST_SCHEME')=='http')
        {
            return $this->redirect('https://www.' . env('SERVER_NAME') . Router::url($this->request->getRequestTarget()));
        }else{
            $split=explode('.',env('SERVER_NAME'));
            if($split[0]!='www'){
                return $this->redirect('https://www.' . env('SERVER_NAME') . Router::url($this->request->getRequestTarget()));
            }
        }
}



RiTeSh
  • 182
  • 11