10000 [Session] cleanup behavior · Issue #12325 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
[Session] cleanup behavior #12325
Closed
Closed
@Tobion

Description

@Tobion

So are dozens of Session bug reports across the Symfony and Silex and other related libraries. Most of them are because of wrong usage or misunderstanding. This ticket sums up how I see sessions should behave after researching many, many tickets.

Session State

    /**
     * Whether the session can be resumed from the previous request.
     *
     * It means that there is a cookie with the given session name.
     *
     * @return bool
     */
    public function isResumable();

    /**
     * Returns whether the session was started.
     *
     * When the session is saved, i.e. not active anymore, it will still return true. It only means that start() was called at least once (directly or indirectly).
     *
     * @return bool
     */
    public function isStarted();

   /**
     * Returns whether the session is currently open, i.e. started but not saved yet.
     *
     * Equivalent to session_status() === PHP_SESSION_ACTIVE. But needs special treatment for PHP 5.3.
     *
     * @return bool
     */
    public function isActive();

Session Usage

Session methods should throw exceptions when misused and when this misuse would cause wrong expectations. If the "misuse" does not cause side-effects or unexpected behavior, it should not throw exceptions.

  • SessionStorage::regenerate should throw exception if no session is active because otherwise it has no effect. This fixes Session invalidate does not work (session not started automatically) silexphp/Silex#746 and https://bugs.php.net/bug.php?id=49462
  • SessionStorage::start should NOT throw an exception because starting a session twice makes no sense but has no downsides.
  • If the session is already started by symfony, just ignore the start (this is already how it is).
  • If the session was started by third party (e.g. facebook sdk) or legacy apps and is still ACTIVE, save and close the third party session and start the symfony session instead so it uses it's configuration (save handler especially). Optionally, one can also merge the current $_SESSION data into the symfony session data, in case you need access to the third party session data from within the symfony session.
  • SessionStorage::save should throw an exception if session is not active because there is something wrong in program logic. You cannot save something that does not exist.
  • SessionStorage::setId should throw an exception if session is active (partly as-is). But the question is why there is a setter at all? There should not be a case where you need to explicitly set an id. It's exactly the point that the id is random and not guessable.

Session Lifecycle

Always save session before sending response / doing a redirect. This will fix many common problems:

Auto-start behavior when reading/writing

See also #6036

  • Reading from the session when there is no session cookie, i.e. there is no previous session: It SHOULD NOT start the session. There is no reason to create a session with a cookie when only reading data. It just means the data is not available as we already know since there is no session. This is also what @TerjeBr suggested. @Drak argument that people need to check themselves whether the session is active is also possible. But the example he gave {% if app.session.isstarted() %}{% for flashMessage in app.session.flashbag.get('notice') %} is wrong. If the session is closed/saved this won't even work and not show the messages. So actually one would need to check Request::hasPreviousSession each time one reads session data at the moment. But the session part does not even have a method for that. So when injecting the session alone (without request) you don't have access to this important method. So in reality, forcing users to check the session state everywhere where they read data is not viable.
  • Reading from the session when there is IS a session cookie . It should auto-start the session which reads the information stored in the session and makes them available. Otherwise reading data would not find the data unless it has been started manually which is also not developer friendly.
  • Reading from the session when the session has already been started in the current request but is currently closed/saved: In this case we don't necessarily need to re-start the session because the data is already available. This is a performance enhancement because it prevents to read the data again that we already have. The only disavantage is that it does not synchronize the data written in another request between your save() and the get(). But this is highly unlikely and rather strange case anway. And devs could just call start() themselves if they want that sync.
  • Writing to the session should always start the session so that the data is actually persisted. Otherwise there would be no point in writing to the session when it's not available in the next request. Zend Session raises an immutable exception when writing to a session that is already closed/saved. But I don't think that's a good idea because then you cannot add session data later in the lifecycle anymore.

Metadata

Metadata

Assignees

No one assigned

    Labels

    HttpFoundationRFCRFC = Request For Comments (proposals about features that you want to be discussed)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0