As you might now, I’m at war with server-side Sessions. Thus (and for a couple of other reasons) I’m uneasy with our current Flash Message implementation.
TL;DR Instead of automagically starting a session as soon as one packages uses Flash Messages, I suggest to make the implementation configurable and I created an alternative implementation to show that this works in fact
Current implementation
Currently Flow (and any other Framework I checked) uses a very simple
approach to Flash Messages:
- A string (or sometimes a more complex object including title, categorization
etc) is stored into the session before a HTTP redirect is triggered. - Upon displaying of the target action, any Flash Message is read and
removed from the session and rendered to the client
Motivation to change this
- Most importantly the current implementation defeats caching[¹]
- Server-side Sessions are not easy to scale
- Storing objects in the session is error prone because the object’s
implementation can change - The FlashMessage container is filled up with old messages if they are
not rendered - An exception is thrown if Flash Messages are used in a context that
doesn’t support sessions (e.g. from the CLI)
Suggestion
I suggest to make the Flash Message implementation a configurable strategy.
By default we could use the current, session-based, implementation because
it requires no further adjustment by the user.
But it should be possible to change that globally – or maybe even per request
pattern (for example in a CLI request it could be rendered to the console
immediately)
A simple implementation we could “ship” by default (in addition to the session-based
one) is one that simply uses a cookie to send the Flash Messages so they can be read
via JavaScript.
I created a simple example of that and it works like a charm:
Other possible implementations
The possibilities to pass data to a successive request are limited, but
there a a few possible other approaches I can think of supporting the idea
to make this a configurable strategy:
Query argument
The Flash Message(s) could be passed to the target URL via query arguments
on the Location
HTTP header.
But as that’s a possible XSS attack vector, these arguments would have to
be signed (i.e. using a JWT with an async, see example using RS256)
Web Notifications
The Notifications API,
possibly together with the Push API
could be used to render messages in the user’s browser.
Further considerations
Some (more technical) thoughts on this:
Security
Using a cookie to store the Flash Message content as plaintext might pose
a risk, because that cookie could be altered by the client.
I added some lines to the packages README
outlining why I don’t consider this an issue.
Changing the PHP API
Not the scope of this RFC but maybe worth mentioning:
In my opinion one should not deal with Flash Messages from within the
MVC code as controllers should act on a different level of domain logic.
Instead I could imagine to have some kind of basic Rules Engine
that
configures Flash Messages based on Domain Events.
This would also allow to re-use the concept outside of MVC.
[¹]: By default the Flash Message is displayed on redirect which is a GET (i.e. safe) request and should be cacheable according to the HTTP specification.
That’s the reason why we can’t use Flash Messages in the Neos Frontend today unless we mark the whole Fusion prototype uncached