Symfony 4 was released on November 30th.
Update now to the best Symfony ever!

You are browsing the Symfony 4 documentation, which changes significantly from Symfony 3.x. If your app doesn't use Symfony 4 yet, browse the Symfony 3.4 documentation.

How to Force Routes to Always Use HTTPS or HTTP

How to Force Routes to Always Use HTTPS or HTTP

Sometimes, you want to secure some routes and be sure that they are always accessed via the HTTPS protocol. The Routing component allows you to enforce the URI scheme via schemes:

  • Annotations
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    // src/Controller/MainController.php
    namespace App\Controller;
    
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    
    class MainController extends Controller
    {
        /**
         * @Route("/secure", name="secure", schemes={"https"})
         */
        public function secure()
        {
            // ...
        }
    }
    
  • YAML
    1
    2
    3
    4
    5
    # config/routes.yaml
    secure:
        path:       /secure
        controller: App\Controller\MainController::secure
        schemes:    [https]
    
  • XML
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    <!-- config/routes.xml -->
    <?xml version="1.0" encoding="UTF-8" ?>
    
    <routes xmlns="http://symfony.com/schema/routing"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
    
        <route id="secure" path="/secure" schemes="https">
            <default key="_controller">App\Controller\MainController::secure</default>
        </route>
    </routes>
    
  • PHP
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    // config/routes.php
    use Symfony\Component\Routing\RouteCollection;
    use Symfony\Component\Routing\Route;
    
    $collection = new RouteCollection();
    $collection->add('secure', new Route('/secure', array(
        '_controller' => 'App\Controller\MainController::secure',
    ), array(), array(), '', array('https')));
    
    return $collection;
    

The above configuration forces the secure route to always use HTTPS.

When generating the secure URL, and if the current scheme is HTTP, Symfony will automatically generate an absolute URL with HTTPS as the scheme, even when using the path() function:

1
2
3
4
5
6
7
{# If the current scheme is HTTPS #}
{{ path('secure') }}
{# generates a relative URL: /secure #}

{# If the current scheme is HTTP #}
{{ path('secure') }}
{# generates an absolute URL: https://example.com/secure #}

The requirement is also enforced for incoming requests. If you try to access the /secure path with HTTP, you will automatically be redirected to the same URL, but with the HTTPS scheme.

The above example uses https for the scheme, but you can also force a URL to always use http.

Note

The Security component provides another way to enforce HTTP or HTTPS via the requires_channel setting. This alternative method is better suited to secure an "area" of your website (all URLs under /admin) or when you want to secure URLs defined in a third party bundle (see How to Force HTTPS or HTTP for different URLs for more details).

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.