The frontend login has changed in TYPO3 12. I try to follow the new documentation.
The authentication of the frontend user works fine, however after the redirect he is not logged in. What is missing in my php code which I have mostly copied from TYPO3 12 Core? What else must be done to log in the front end user automatically without a form view?
<?php
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Core\Crypto\PasswordHashing\SaltedPasswordService;
use TYPO3\CMS\Core\Context\UserAspect;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Session\SessionManager;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class System implements LoggerAwareInterface
{
use LoggerAwareTrait;
/**
* @var SessionBackendInterface
*/
protected $sessionBackend;
public $loginType = 'FE';
public function login(
ContentObjectRenderer $cObj,
Localization $languageObj,
Parameters $controlData,
Url $url,
$conf,
$username,
$cryptedPassword,
$requiresAuthorization = true,
$redirect = true
) {
$result = true;
$ok = true;
$authenticated = false;
$message = '';
$authServiceObj = null;
$request = $controlData->getRequest();
$frontendUser = $controlData->getFrontendUser();
$user = [];
// Log the user in
$loginData = [
'uname' => $username,
'uident' => $cryptedPassword,
'uident_text' => $cryptedPassword,
'status' => 'login',
];
// Check against configured pid (defaulting to current page)
$frontendUser->checkPid = true;
$pageIds = ($cObj->data['pages'] ? $cObj->data['pages'] . ',' : '') . $controlData->getPid();
$frontendUser->checkPid_value =
SystemUtility::getRecursivePids(
$pageIds,
$cObj->data['recursive']
);
// Get authentication info array
$authInfo = $frontendUser->getAuthInfoArray($request);
if ($requiresAuthorization) {
$ok = false;
$serviceKeyArray = [];
$serviceKeyArray[] = SaltedPasswordService::class;
if (
$conf['authServiceClass'] != '' &&
$conf['authServiceClass'] != '{$plugin.tx_agency.authServiceClass}' &&
class_exists($conf['authServiceClass'])
) {
$serviceKeyArray = array_merge($serviceKeyArray, GeneralUtility::trimExplode(',', $conf['authServiceClass']));
}
$serviceChain = '';
$ok = false;
while (
!$ok &&
is_object(
$authServiceObj =
GeneralUtility::makeInstanceService(
'auth',
'authUserFE',
GeneralUtility::trimExplode(',', $serviceChain, true)
)
)
) {
$subType = 'authUserFE';
$isProcessed =
$authServiceObj->processLoginData($loginData, 'normal');
if (!$isProcessed) {
continue;
}
$authServiceObj->initAuth($subType, $loginData, $authInfo, $frontendUser);
// Get user info
$user =
$authServiceObj->fetchUserRecord(
$loginData['uname']
// $authInfo['db_user'],
);
if (
!empty($user) &&
($ret = $authServiceObj->authUser($user)) > 0
) {
// If the service returns >=200 then no more checking is needed - useful for IP checking without password
if ((int)$ret >= 200) {
$ok = true;
$authenticated = true;
} else if ((int)$ret >= 100) {
// nothing
} else {
$ok = true;
$authenticated = true;
}
} else {
$authenticated = false;
break;
}
if (!empty($user)) {
$serviceChain .= ',' . $authServiceObj->getServiceKey();
}
}
} else {
$ok = true;
}
if ($ok && $authenticated) {
// Enforce session so we get a FE cookie. Otherwise autologin might not work :
$frontendUser->storeSessionData();
$frontendUser->setAndSaveSessionData('login', true);
// Login successfull: create user session
$sessionRecord = $frontendUser->createUserSession($user);
if (isset($authInfo['userSession']['ses_data'])) {
// Preserve session data on login
$sessionData = $this->getSessionBackend()->update(
$frontendUser->id,
['ses_data' => $authInfo['userSession']['ses_data']]
);
$frontendUser->user = array_merge(
$user,
$sessionData
);
} else {
$frontendUser->user = $user;
}
// The login session is started.
$frontendUser->loginSessionStarted = true;
// $frontendUser->createUserAspect();
// $aspect = GeneralUtility::makeInstance(UserAspect::class, $frontendUser);
// $context = GeneralUtility::makeInstance(Context::class);
// $context->setAspect('frontend.user', $aspect);
} elseif (
is_object($authServiceObj) &&
in_array(get_class($authServiceObj), $serviceKeyArray)
) {
if (empty($user)) {
// No enabled user of the given name
$message = sprintf($languageObj->getLabel('internal_no_enabled_user'), $loginData['uname']);
} else {
// auto login failed...
$message = $languageObj->getLabel('internal_auto_login_failed');
}
$result = false;
} else {
// Required authentication service not available
$message = $languageObj->getLabel('internal_required_authentication_service_not_available');
$result = false;
}
// Delete regHash
if (
$controlData->getValidRegHash()
) {
$regHash = $controlData->getRegHash();
$controlData->deleteShortUrl($regHash);
}
if ($result == false) {
if (strlen($message)) {
$this->logger->critical($message);
}
$ok = false;
}
if (
$ok &&
$redirect
) {
// Redirect to configured page, if any
$redirectUrl = $controlData->readRedirectUrl();
if (!$redirectUrl && $result == true) {
$redirectUrl = trim($conf['autoLoginRedirect_url']);
}
if (!$redirectUrl) {
if ($conf['loginPID']) {
$redirectUrl = $url->get($conf['loginPID'], '', [], ['regHash']);
} else {
$redirectUrl = $controlData->getSiteUrl();
}
}
header('Location: ' . GeneralUtility::locationHeaderUrl($redirectUrl));
}
return $result;
}
/**
* Returns initialized session backend. Returns same session backend if called multiple times
*
* @return SessionBackendInterface
*/
protected function getSessionBackend()
{
if (!isset($this->sessionBackend)) {
$this->sessionBackend = GeneralUtility::makeInstance(SessionManager::class)->getSessionBackend($this->loginType);
}
return $this->sessionBackend;
}
}