Password hashing and migration improvements

Robin Chalas
Contributed by Robin Chalas in #34020 and #34139

In Symfony 4.3 we introduced the native password encoder to let Symfony select the best algorithm to hash passwords automatically. This is still the recommended setting, but some applications must stick to some specific algorithm for some reasons.

That's why in Symfony 4.4 we've un-deprecated all the specific encoders, so you can use them again in your security config:

1
2
3
4
5
6
7
8
9
10
# config/packages/security.yaml
security:
    # ...
    encoders:
        App\Entity\User:
            algorithm: 'argon2i'
            algorithm: 'argon2id'
            algorithm: 'auto'
            algorithm: 'bcrypt'
            algorithm: 'sodium'

Related to this and to password migration, we've added a new migrate_from option to allow encoders define their original algorithm when migrating to a new encoder:

1
2
3
4
5
6
7
# config/packages/security.yaml
security:
    # ...
    encoders:
        App\Entity\User:
            algorithm: 'argon2i'
            migrate_from: 'bcrypt'

Deprecated WebserverBundle

Hamza Amrouche
Contributed by Hamza Amrouche in #31217

The WebServerBundle is a thin wrapper on top of PHP's built-in web server. A few years ago it was useful to quickly run projects on your local machine. However, since we introduced the Symfony local web server, the WebServerBundle pales in comparison.

For starters, WebServerBundle is much slower because it can only serve one request at a time (Symfony's server loads them in parallel). In addition, it's not ready for modern applications because it doesn't support HTTPS, whereas Symfony's server supports that and generates certificates for you automatically.

Symfony's server provides many other utilities that you'll need while developing your application locally, such as local domain names, different PHP settings per project and smooth Docker integration.

That's why we've deprecated WebServerBundle in Symfony 4.4 (and removed it in Symfony 5.0). As an alternative, use the Symfony server provided when you install Symfony in your computer.

Faster container compilation

Nicolas Grekas
Contributed by Nicolas Grekas in #33701

The service container compilation can take some time in the development environment when the application defines lots of services. When two or more concurrent requests need to compile the container, this can lead to long waits.

In Symfony 4.4, we wrapped the container compilation in an opportunistic lock so only the first request compiles it while the other requests wait. In practice this makes the compilation noticeable faster in the development environment.

Simpler YAML redirection config

Yonel Ceruto
Contributed by Yonel Ceruto in #33217

Redirecting to another URL or route in a controller is simple thanks to the classes and shortcuts provided by Symfony. However, configuring an HTTP redirection in YAML files is not that simple because of the verbosity of referring to PHP controllers. For example:

1
2
3
4
5
6
7
8
9
10
11
12
# config/routes.yaml
doc_shortcut:
    path: /doc
    controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::redirectAction
    defaults:
        route: 'doc_page'

legacy_doc:
    path: /legacy/doc
    controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController::urlRedirectAction
    defaults:
        path: 'https://legacy.example.com/doc'

In Symfony 4.4 we improved this a bit by making the RedirectController invokable. The previous routing config looks as follows in Symfony 4.4:

1
2
3
4
5
6
7
8
9
10
11
12
# config/routes.yaml
doc_shortcut:
    path: /doc
    controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController
    defaults:
        route: 'doc_page'

legacy_doc:
    path: /legacy/doc
    controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController
    defaults:
        path: 'https://legacy.example.com/doc'

Easier to understand exceptions

Ruud Kamphuis
Contributed by Ruud Kamphuis in #31514

When running tests is common to see in the console the rendered HTML page of some exceptions. This HTML page is usually so long that it's difficult to find the main exception message. In Symfony 4.4 we improved this by including the main exception message twice as HTML comments inside the exception page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html>
    <!-- Notice: Undefined index: payouts in /Volumes/CS/www/src/Generated/GraphQL/
         Query/TransactionList/Data.php line 33 (500 Internal Server Error) -->
    <head>
        <meta charset="UTF-8">
        <meta name="robots" content="noindex,nofollow">
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <title>    Notice: Undefined index: payouts in /Volumes/CS/www/src/Generated/GraphQL/Query/TransactionList/Data.php line 33 (500 Internal Server Error)
</title>
        <link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAgCAYAAAABtRhCAAADVUlEQVRIx82XX0jTURTHLYPyqZdefQx66CEo80+aYpoIkqzUikz6Z5klQoWUWYRIJYEUGpQ+lIr9U5dOTLdCtkmWZis3rbnC5fw/neYW002307mX/cZvP3/7o1PwwOdh95x7vnf39zvnd29AgBer2xO6DclAXiMqZAqxIiNIN/IYSUS2BPhjmGATchUxI+ADWiRhpWK7HKuHFVBFdmU5YvnI4grFGCaReF/EBH4KsZlGgj2JBTuCYBWRIYF8YoEOJ6wBt/gEs7mBbyOjQXruPLSdOgPCiEiPSUUHDoL8Ug5IUo9B/d5wrt+G7OAKNrODPuVdB6vRCIzN6SdBlpW9RIgk/1FeAXabzRlrUPVCS/JhbmwudztnGeeH9AyXBIwtmM3wLinZJZHifjHw2V+NBoRh+9ixQrbgbnaSIcl7cGea6hoXQbNe7za241oeO5Z0p42M4BV2EqP2D50wo+6HzvwC6C4sApNOR8cmOrtcnhtj2kYRyC9eBvXzKrBZrXSs72kFd1t3MoKVbMekQkEnSNKOO8fac3LpmK6l1TlGtsxmsdKFsecPYgwxst0cwROMYDXboSotg0WLBRqjY51jLYcENElXwW2XJKPydvoI2GN9T8rBtrAArYIUruBJXkFheCQYlCpQP6uk5dAQFQNaUROMSGVQFxLmkoQsxDJrhLbTZ+nvVsERME9MgPJRKV/58AsyomTSzE813WLFvWK++qI0xSfQl8k8Pg46sYRuv5t6dS+4RqxDwaa4BGjYH+NTQvKScIp9+YL/hoZh3jDtLRHtt2C3g6bmhX+CpsFBWg7ilDSPgj0lD2ncr5ev/BP8VvyAJhqVyZeUhPOrEhEFxgEtjft846Z/guQTNT89Q5P9flMLoth4F7808wKtWWKzAwNQHxrh/1vaid2F+XpYTSbQf1XA2McOmOpROnvpvMEA4tSjq1cW0sws2gCYxswY6TKkvzYnJq1NHZLnRU4BX+4U0uburvusu8Kv8iHY7qefkM4IFngJHEOUXmLEPgiGsI8YnlZILit3vSSLRTQe/MPIZva5pshNIEmyFQlCvruJKXPkCEfmePzkphXHdzZNQdoRI9KPlBAxlj/I8U97ERPS5bjGbWDFbEdqHVe5caTBeZZx2H/IMvzeN15yoQAAAABJRU5ErkJggg==%0A">

       <!-- ... clip ... -->

    Sfjs.addEventListener(document, 'DOMContentLoaded', function() {
        Sfjs.createTabs();
        Sfjs.createToggles();
        Sfjs.createFilters();
    });

/*]]>*/</script>

    </body>
</html>
<!-- Notice: Undefined index: payouts in /Volumes/CS/www/src/Generated/GraphQL/
     Query/TransactionList/Data.php line 33 (500 Internal Server Error) -->
Published in #Living on the edge