New in Symfony 4.4: Lazy Firewalls

Contributed by
Nicolas Grekas
in #33676.
In Symfony's Security component, firewalls configure how your users will be able to authenticate (e.g. using a login form, an API token, etc). Firewalls also configure which URLs they cover and whether anonymous users are allowed to browse those URLs or not:
1 2 3 4 5 6 7 8
# config/packages/security.yaml
security:
# ...
firewalls:
main:
pattern: ^/
anonymous: ~
# ...
When a stateful firewall is configured, a user token is always created from the session for every request, no matter if the user is actually used or not by the application. This means that all those responses are uncacheable (because they use the session).
In Symfony 4.4, firewalls can define lazy
as the value of their anonymous
configuration option:
1 2 3 4 5 6 7 8
# config/packages/security.yaml
security:
# ...
firewalls:
main:
pattern: ^/
anonymous: lazy
# ...
This tells Symfony to only load the user (and start the session) if the
application actually access the user object (e.g. via a is_granted()
call
in a template or a isGranted()
call in a controller or service). This means
that all those URLs/actions that don't need the user will now be public and
cacheable, improving the performance of your application.
Help the Symfony project!
As with any Open-Source project, contributing code or documentation is the most common way to help, but we also have a wide range of sponsoring opportunities.
Comments
Comments are closed.
To ensure that comments stay relevant, they are closed for old posts.
# security.yaml
auth:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: fos_user_security_login
check_path: fos_user_security_check
# csrf_token_generator: security.csrf.token_manager
remember_me:
secret: '%kernel.secret%'
lifetime: 604800 # 1 week in seconds
path: /
samesite: lax
logout: true
anonymous: lazy
Enabling lazy means the rememberMe cookie is not read unless the app accesses the user (via the token storage). If you're testing rememberMe on a page that doesn't access the user, it won't have any effect. Try on a page that reads the user instead (and open an issue with a reproducer if that still doesn't work as expected.)