rishad2m8
rishad2m8

Reputation: 1508

Force HTTPS on Yii2

Requirement

How to forcibly redirect to https (redirect if user accessing http) on Yii2? I already tried web.config to force https, but it didn't work.

scenario

I am using Yii2 advanced app hosted on IIS 7.5.

Upvotes: 2

Views: 9305

Answers (3)

ttrasn
ttrasn

Reputation: 4851

Just add your rule in on beforeAction event on config.php.

'on beforeAction' => function ($event) {
    if (!(
          (!empty($_SERVER['HTTPS']) AND $_SERVER['HTTPS'] != 'off') || 
          $_SERVER['SERVER_PORT'] == 443
        )) {
            return Yii::$app->controller->redirect("https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
    }
}

This code check if user request is not http then move it to https.

From the PHP.net documentation :

for $_SERVER['HTTPS']

Set to a non-empty value if the script was queried through the HTTPS protocol.

Note: Note that when using ISAPI with IIS, the value will be off if the request was not made through the HTTPS protocol.

so this code should works for IIS.

for $_SERVER['SERVER_PORT']:

Note: Under the Apache 2, you must set UseCanonicalName = On, as well as UseCanonicalPhysicalPort = On in order to get the physical (real) port, otherwise, this value can be spoofed and it may or may not return the physical port value. It is not safe to rely on this value in security-dependent contexts.

so if you have any problem in this code, you can prevent to using $_SERVER['SERVER_PORT'] in rule.

At the end, If you want to do in whole advanced Yii2 do this config in common directory.

Upvotes: 1

rishad2m8
rishad2m8

Reputation: 1508

It's very simple on IIS. Can use rewrite module to solve this issue. E.g.,

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>

    <!-- Other stuffs -->

        <rewrite>
            <rules>
                <clear />
                <rule name="Redirect to https" stopProcessing="true">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" ignoreCase="true" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
                </rule>

                <rule name="Hide Yii Index" stopProcessing="true">
                    <match url="." ignoreCase="false" />
                    <conditions>
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="index.php" appendQueryString="true" />        
                </rule>


            </rules>
        </rewrite>

    <!-- Other stuffs -->
    </system.webServer>    
</configuration>

It's very effective and fast. Can used for CDN url of our own without help of PHP code.
This code can used for ASP.Net also. In such case, remove Hide Yii Index section.

Upvotes: 0

PLM57
PLM57

Reputation: 1296

Its actually very easy in Yii2 as there is a predefined method for your check. Just three steps needed:

1. Extend the application class

Extend the default yii web-application class and override the handleRequest-method. Use the existing Yii2-function to check if the connection is secure.

class MyApplication extends \yii\web\Application
{
    public function handleRequest($request)
    {
        //check if connection is secure
        if (!$request->isSecureConnection) {
            //otherwise redirect to same url with https
            $secureUrl= str_replace('http', 'https', $request->absoluteUrl);
            //use 301 for a permanent redirect
            return Yii::$app->getResponse()->redirect($secureUrl, 301);
        } else {
            //if secure connection call parent implementation
            return parent::handleRequest($request);
        }
    }
}

2. Use new class in index.php

Within the index.php of your web-folder simply use your new application-class instead of the regular one where the application-instance is created.

3. Done!

That's it actually... :)! Hope it helps!

Upvotes: 6

Related Questions