Breaking: #93023 - Reworked session handling

See forge#93023

Description

The overall session handling withing TYPO3 Core has been overhauled. This was done to separate the actual User object, the Authentication process and the session handling.

The main result of this refactoring is the user authentication objects such as BackendUserAuthentication and FrontendUserAuthentication do not longer contain the session data directly. Instead this is now encapsulated in a UserSession object which is handled by the new UserSessionManager.

Furthermore the user authentication objects internally do not longer know about a specific session backend implementation, since this is also wrapped by the UserSessionManager. This also means it is not possible to create sessions outside of the new session manager anymore.

For this purpose there are several changes within the user authentication classes which are described below.

The array AbstractUserAuthentication->user previously contained the logged-in user record (from be_users / fe_users database table) AND the session record prefixed via ses_* array properties. This has been removed, to separate the functionality. Instead, all session properties are placed inside the UserSession object, accessible via e.g. $GLOBALS[BE_USER]->getSession().

The following public properties within AbstractUserAuthentication and its subclasses have been removed:

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->id

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->hash_length

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->sessionTimeout

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->gc_time

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->gc_probability

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->newSessionID

The following public methods within AbstractUserAuthentication and its subclasses have been removed:

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->getNewSessionRecord()

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->getSessionId()

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->isExistingSessionRecord()

The following public property within AbstractUserAuthentication has changed their visibility to protected:

  • TYPO3\CMS\Core\Authentication\AbstractUserAuthentication->lifetime

The following public methods within AbstractUserAuthentication and its subclasses have changed their return type:

  • TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication->createUserSession() now returns TYPO3\CMS\Core\Session\UserSession and the first parameter $tempuser is now type-hinted array.

The following public properties within FrontendUserAuthentication have been removed:

  • TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication->sesData_change

The following database fields have been removed:

  • be_sessions.ses_backuserid

  • fe_sessions.ses_anonymous

Impact

Accessing a dropped property or calling a dropped method will raise a fatal PHP error.

Accessing a property whose visibility was changed to protected will also raise a fatal PHP error if no deprecation functionality is in place. See Deprecation: #93023 - Reworked session handling for more information.

Calling a method whose parameter signature changed with a wrong type will raise a PHP type error.

Directly querying a dropped database field will raise a doctrine dbal exception.

Affected Installations

All TYPO3 installations with custom extensions directly accessing or calling the changed properties or methods.

Migration

The sessionTimeout property is now set internally to the value of the global configuration (int)$GLOBALS['TYPO3_CONF_VARS'][$loginType]['sessionTimeout'];. This value can also be set dynamically in e.g. a middleware if needed. Because it is only needed for User Session objects, it is now resolved within the UserSessionManager object.

gc_time is still set to 86400 per default and will be overwritten with the value from sessionTimeout (see above) if greater than 0.

Since it's very unlikely that gc_probability will be changed in custom code there is no direct way to set a custom value anymore. It's now directly set to 1 in the consuming method UserSessionManager->collectGarbage(). If your custom code however rely on another value you can call UserSessionManager->collectGarbage() in your code by providing a custom value as first argument for $garbageCollectionProbability.

The property newSessionID is now available in UserSession->isNew().

Use the UserSessionManager->elevateToFixatedUserSession() as a replacement for getNewSessionRecord() to migrate an anonymous session to a user-bound session.

If you directly call createUserSession() in your custom code make sure to pass an array as argument for $tempuser and to handle the returned UserSession object accordingly.

Use UserSession->dataWasUpdated() as replacement for FrontendUserAuthentication->sesData_change.

The be_sessions.ses_backuserid field was migrated into the session data and is now available inside UserSession->data, which can be accessed using get() or getAll(). Since this value is only present in "switch-user" sessions, it's very unlikely that custom code is directly accessing it. If you however perform database queries using this field, then they have to be adjusted accordingly.

The fe_sessions.ses_anonymous field is not needed anymore since this information can also be obtained using the fe_sessions.ses_userid field. If it's lower or equals 0 the session is an anonymous one. If you perform database queries using this field, change it to use use ses_userid instead. If a session is anonymous can furthermore be checked using UserSession->isAnonymous().