‪TYPO3CMS  ‪main
LoginController.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\EventDispatcher\EventDispatcherInterface;
21 use Psr\Http\Message\ResponseInterface;
22 use Psr\Http\Message\ServerRequestInterface;
23 use Symfony\Component\HttpFoundation\Cookie;
53 
59 #[AsController]
61 {
63 
69  protected ‪$redirectUrl;
70 
76  protected ‪$redirectToURL;
77 
81  protected string ‪$loginProviderIdentifier = '';
82 
90  protected ‪$loginRefresh;
91 
97  protected ‪$submitValue;
98 
102  protected ‪$view;
103 
107  protected ServerRequestInterface ‪$request;
108 
109  public function ‪__construct(
110  protected readonly ‪Typo3Information $typo3Information,
111  protected readonly EventDispatcherInterface $eventDispatcher,
112  protected readonly ‪PageRenderer $pageRenderer,
113  protected readonly ‪UriBuilder $uriBuilder,
114  protected readonly ‪Features $features,
115  protected readonly ‪Context $context,
116  protected readonly ‪LoginProviderResolver $loginProviderResolver,
117  protected readonly ‪ExtensionConfiguration $extensionConfiguration,
118  protected readonly ‪BackendEntryPointResolver $backendEntryPointResolver,
119  protected readonly ‪FormProtectionFactory $formProtectionFactory,
120  protected readonly ‪Locales $locales,
121  ) {}
122 
127  public function ‪formAction(ServerRequestInterface ‪$request): ResponseInterface
128  {
129  $this->request = ‪$request;
130  $this->‪init($request);
131  $response = $this->‪createLoginLogoutForm($request);
132  return $this->‪appendLoginProviderCookie($request, ‪$request->getAttribute('normalizedParams'), $response);
133  }
134 
138  public function ‪refreshAction(ServerRequestInterface ‪$request): ResponseInterface
139  {
140  $this->request = ‪$request;
141  $this->‪init($request);
142  $this->loginRefresh = true;
143  $response = $this->‪createLoginLogoutForm($request);
144  return $this->‪appendLoginProviderCookie($request, ‪$request->getAttribute('normalizedParams'), $response);
145  }
146 
151  public function ‪requestTokenAction(ServerRequestInterface ‪$request): ResponseInterface
152  {
153  return new ‪JsonResponse([
154  'headerName' => ‪RequestToken::HEADER_NAME,
155  'requestToken' => $this->‪provideRequestTokenJwt(),
156  ]);
157  }
158 
163  public function ‪getLoginProviderIdentifier(): string
164  {
166  }
167 
171  public function ‪getCurrentRequest(): ServerRequestInterface
172  {
173  return ‪$this->request;
174  }
175 
180  protected function ‪appendLoginProviderCookie(ServerRequestInterface ‪$request, ‪NormalizedParams $normalizedParams, ResponseInterface $response): ResponseInterface
181  {
182  if ($this->loginProviderIdentifier === $this->loginProviderResolver->getPrimaryLoginProviderIdentifier()) {
183  return $response;
184  }
185  // Use the secure option when the current request is served by a secure connection
186  $cookie = new Cookie(
187  'be_lastLoginProvider',
188  $this->loginProviderIdentifier,
189  ‪$GLOBALS['EXEC_TIME'] + 7776000, // 90 days
190  $this->backendEntryPointResolver->getPathFromRequest(‪$request),
191  '',
192  $normalizedParams->‪isHttps(),
193  true,
194  false,
195  Cookie::SAMESITE_STRICT
196  );
197  return $response->withAddedHeader('Set-Cookie', $cookie->__toString());
198  }
199 
203  protected function ‪init(ServerRequestInterface ‪$request): void
204  {
205  $languageService = $this->‪getLanguageService();
206  $backendUser = $this->‪getBackendUserAuthentication();
207  $parsedBody = ‪$request->getParsedBody();
208  $queryParams = ‪$request->getQueryParams();
209 
210  // Try to get the preferred browser language
211  $httpAcceptLanguage = ‪$request->getServerParams()['HTTP_ACCEPT_LANGUAGE'] ?? '';
212  $preferredBrowserLanguage = $this->locales->getPreferredClientLanguage($httpAcceptLanguage);
213 
214  // If we found a $preferredBrowserLanguage, which is not the default language, while no user is logged in,
215  // initialize $this->getLanguageService() and set the language to the backend user object, so labels in fluid
216  // views are translated
217  if (empty($backendUser->user['uid'])) {
218  $languageService->init($this->locales->createLocale($preferredBrowserLanguage));
219  $backendUser->user['lang'] = $preferredBrowserLanguage;
220  }
221 
222  $this->‪setUpBasicPageRendererForBackend($this->pageRenderer, $this->extensionConfiguration, ‪$request, $languageService);
223  $this->pageRenderer->setTitle('TYPO3 CMS Login: ' . (‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] ?? ''));
224 
225  $this->redirectUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['redirect_url'] ?? $queryParams['redirect_url'] ?? '');
226  $this->loginProviderIdentifier = $this->loginProviderResolver->resolveLoginProviderIdentifierFromRequest(‪$request, 'be_lastLoginProvider');
227 
228  $this->loginRefresh = (bool)($parsedBody['loginRefresh'] ?? $queryParams['loginRefresh'] ?? false);
229  // Value of "Login" button. If set, the login button was pressed.
230  $this->submitValue = $parsedBody['commandLI'] ?? $queryParams['commandLI'] ?? null;
231 
232  // Setting the redirect URL to "index.php?M=main" if no alternative input is given
233  if ($this->redirectUrl) {
234  $this->redirectToURL = ‪$this->redirectUrl;
235  } else {
236  // (consolidate RouteDispatcher::evaluateReferrer() when changing 'main' to something different)
237  $this->redirectToURL = (string)$this->uriBuilder->buildUriWithRedirect('main', [], ‪RouteRedirect::createFromRequest(‪$request));
238  }
239 
240  // If "L" is "OUT", then any logged in is logged out. If redirect_url is given, we redirect to it
241  if (($parsedBody['L'] ?? $queryParams['L'] ?? null) === 'OUT' && is_object($backendUser)) {
242  $backendUser->logoff();
243  $this->‪redirectToUrl();
244  }
245 
246  // @todo: This should be ViewInterface. But this breaks LoginProviderInterface AND ModifyPageLayoutOnLoginProviderSelectionEvent
247  $this->view = GeneralUtility::makeInstance(StandaloneView::class);
248  // StandaloneView should NOT receive a request at all, override the default StandaloneView constructor here.
249  $this->view->setRequest();
250  $this->view->setTemplateRootPaths(['EXT:backend/Resources/Private/Templates']);
251  $this->view->setLayoutRootPaths(['EXT:backend/Resources/Private/Layouts']);
252  $this->view->setPartialRootPaths(['EXT:backend/Resources/Private/Partials']);
254  $this->view->assign('referrerCheckEnabled', $this->features->isFeatureEnabled('security.backend.enforceReferrer'));
255  $this->view->assign('loginUrl', (string)‪$request->getUri());
256  $this->view->assign('loginProviderIdentifier', $this->loginProviderIdentifier);
257  }
258 
259  protected function ‪provideCustomLoginStyling(): void
260  {
261  $languageService = $this->‪getLanguageService();
262  $authenticationStyleInformation = GeneralUtility::makeInstance(AuthenticationStyleInformation::class);
263  if (($backgroundImageStyles = $authenticationStyleInformation->getBackgroundImageStyles()) !== '') {
264  $this->pageRenderer->addCssInlineBlock('loginBackgroundImage', $backgroundImageStyles, useNonce: true);
265  }
266  if (($footerNote = $authenticationStyleInformation->getFooterNote()) !== '') {
267  $this->view->assign('loginFootnote', $footerNote);
268  }
269  if (($highlightColorStyles = $authenticationStyleInformation->getHighlightColorStyles()) !== '') {
270  $this->pageRenderer->addCssInlineBlock('loginHighlightColor', $highlightColorStyles, useNonce: true);
271  }
272  if (($logo = $authenticationStyleInformation->getLogo()) !== '') {
273  $logoAlt = $authenticationStyleInformation->getLogoAlt() ?: $languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang_login.xlf:typo3.altText');
274  } else {
275  $logo = $authenticationStyleInformation->getDefaultLogo();
276  $logoAlt = $languageService->sL('LLL:EXT:backend/Resources/Private/Language/locallang_login.xlf:typo3.altText');
277  $this->pageRenderer->addCssInlineBlock('loginLogo', $authenticationStyleInformation->getDefaultLogoStyles(), useNonce: true);
278  }
279  $this->view->assignMultiple([
280  'logo' => $logo,
281  'logoAlt' => $logoAlt,
282  'images' => $authenticationStyleInformation->getSupportingImages(),
283  'copyright' => $this->typo3Information->getCopyrightNotice(),
284  ]);
285  }
286 
290  protected function ‪createLoginLogoutForm(ServerRequestInterface ‪$request): ResponseInterface
291  {
292  $backendUser = $this->‪getBackendUserAuthentication();
293 
294  // Checking, if we should make a redirect.
295  // Might set JavaScript in the header to close window.
296  $this->‪checkRedirect($request);
297 
298  // Show login form
299  if (empty($backendUser->user['uid'])) {
300  $action = 'login';
301  $formActionUrl = $this->uriBuilder->buildUriWithRedirect(
302  'login',
303  [
304  'loginProvider' => $this->loginProviderIdentifier,
305  ],
307  );
308  } else {
309  // Show logout form
310  $action = 'logout';
311  $formActionUrl = $this->uriBuilder->buildUriFromRoute('logout');
312  }
313  $this->view->assignMultiple([
314  'backendUser' => $backendUser->user,
315  'hasLoginError' => $this->isLoginInProgress(‪$request),
316  'action' => $action,
317  'formActionUrl' => $formActionUrl,
318  'requestTokenName' => ‪RequestToken::PARAM_NAME,
319  'requestTokenValue' => $this->provideRequestTokenJwt(),
320  'forgetPasswordUrl' => $this->uriBuilder->buildUriWithRedirect(
321  'password_forget',
322  ['loginProvider' => $this->loginProviderIdentifier],
324  ),
325  'redirectUrl' => $this->redirectUrl,
326  'loginRefresh' => $this->loginRefresh,
327  'loginProviders' => $this->loginProviderResolver->getLoginProviders(),
328  'loginNewsItems' => $this->getSystemNews(),
329  ]);
330 
331  // Initialize interface selectors:
333 
334  $this->pageRenderer->setBodyContent('<body>' . $this->view->render());
335  return $this->pageRenderer->renderResponse();
336  }
337 
338  protected function ‪renderHtmlViaLoginProvider(): void
339  {
340  $loginProviderConfiguration = $this->loginProviderResolver->getLoginProviderConfigurationByIdentifier($this->loginProviderIdentifier);
342  $loginProvider = GeneralUtility::makeInstance($loginProviderConfiguration['provider']);
343  $this->eventDispatcher->dispatch(
345  $this,
346  $this->view,
347  $this->pageRenderer
348  )
349  );
350  $loginProvider->render($this->view, $this->pageRenderer, $this);
351  }
352 
361  protected function ‪checkRedirect(ServerRequestInterface ‪$request): void
362  {
363  $backendUser = $this->‪getBackendUserAuthentication();
364  if (empty($backendUser->user['uid'])) {
365  return;
366  }
367 
368  // If no cookie has been set previously, we tell people that this is a problem.
369  // This assumes that a cookie-setting script (like this one) has been hit at
370  // least once prior to this instance.
371  if (!isset(‪$request->getCookieParams()[‪BackendUserAuthentication::getCookieName()])) {
372  if ($this->submitValue === 'setCookie') {
373  // we tried it a second time but still no cookie
374  throw new \RuntimeException('Login-error: Yeah, that\'s a classic. No cookies, no TYPO3. ' .
375  'Please accept cookies from TYPO3 - otherwise you\'ll not be able to use the system.', 1294586846);
376  }
377  // try it once again - that might be needed for auto login
378  $this->redirectToURL = 'index.php?commandLI=setCookie';
379  }
380  $redirectToUrl = (string)($backendUser->getTSConfig()['auth.']['BE.']['redirectToURL'] ?? '');
381  if (!empty($redirectToUrl)) {
382  $this->redirectToURL = $redirectToUrl;
383  } else {
384  // (consolidate RouteDispatcher::evaluateReferrer() when changing 'main' to something different)
385  $this->redirectToURL = (string)$this->uriBuilder->buildUriWithRedirect('main', [], ‪RouteRedirect::createFromRequest(‪$request));
386  }
387 
388  $formProtection = $this->formProtectionFactory->createFromRequest(‪$request);
389  if (!$formProtection instanceof BackendFormProtection) {
390  throw new \RuntimeException('The Form Protection retrieved does not match the expected one.', 1432080411);
391  }
392  if ($this->loginRefresh) {
393  $formProtection->setSessionTokenFromRegistry();
394  $formProtection->persistSessionToken();
395  // triggering `TYPO3/CMS/Backend/LoginRefresh` module happens in `TYPO3/CMS/Backend/Login`
396  } else {
397  $formProtection->storeSessionTokenInRegistry();
398  $this->‪redirectToUrl();
399  }
400  }
401 
406  protected function ‪getSystemNews(): array
407  {
408  $systemNewsTable = 'sys_news';
409  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
410  ->getQueryBuilderForTable($systemNewsTable);
411  $systemNews = [];
412  $systemNewsRecords = $queryBuilder
413  ->select('uid', 'title', 'content', 'crdate')
414  ->from($systemNewsTable)
415  ->orderBy('crdate', 'DESC')
416  ->executeQuery()
417  ->fetchAllAssociative();
418  foreach ($systemNewsRecords as $systemNewsRecord) {
419  $systemNews[] = [
420  'uid' => $systemNewsRecord['uid'],
421  'date' => $systemNewsRecord['crdate'] ? date(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['ddmmyy'], (int)$systemNewsRecord['crdate']) : '',
422  'header' => $systemNewsRecord['title'],
423  'content' => $systemNewsRecord['content'],
424  ];
425  }
426  return $systemNews;
427  }
428 
432  protected function ‪isLoginInProgress(ServerRequestInterface ‪$request): bool
433  {
434  $parsedBody = ‪$request->getParsedBody();
435  $queryParams = ‪$request->getQueryParams();
436  $username = $parsedBody['username'] ?? $queryParams['username'] ?? null;
437  return !empty($username) || !empty($this->submitValue);
438  }
439 
445  protected function ‪redirectToUrl(): void
446  {
447  throw new ‪PropagateResponseException(new ‪RedirectResponse($this->redirectToURL, 303), 1607271511);
448  }
449 
450  protected function ‪provideRequestTokenJwt(): string
451  {
452  $nonce = ‪SecurityAspect::provideIn($this->context)->provideNonce();
453  return ‪RequestToken::create('core/user-auth/be')->toHashSignedJwt($nonce);
454  }
455 
456  protected function ‪getLanguageService(): ‪LanguageService
457  {
458  return ‪$GLOBALS['LANG'];
459  }
460 
462  {
463  return ‪$GLOBALS['BE_USER'];
464  }
465 }
‪TYPO3\CMS\Core\Context\SecurityAspect\provideIn
‪static provideIn(Context $context)
Definition: SecurityAspect.php:41
‪TYPO3\CMS\Backend\View\AuthenticationStyleInformation
Definition: AuthenticationStyleInformation.php:32
‪TYPO3\CMS\Backend\Controller\LoginController\$redirectToURL
‪string $redirectToURL
Definition: LoginController.php:73
‪TYPO3\CMS\Backend\LoginProvider\LoginProviderInterface
Definition: LoginProviderInterface.php:26
‪TYPO3\CMS\Backend\Controller\LoginController\getLoginProviderIdentifier
‪getLoginProviderIdentifier()
Definition: LoginController.php:157
‪TYPO3\CMS\Core\Security\RequestToken\HEADER_NAME
‪const HEADER_NAME
Definition: RequestToken.php:29
‪TYPO3\CMS\Core\Information\Typo3Information
Definition: Typo3Information.php:28
‪TYPO3\CMS\Backend\LoginProvider\Event\ModifyPageLayoutOnLoginProviderSelectionEvent
Definition: ModifyPageLayoutOnLoginProviderSelectionEvent.php:26
‪TYPO3\CMS\Core\Configuration\ExtensionConfiguration
Definition: ExtensionConfiguration.php:47
‪TYPO3\CMS\Backend\Controller\LoginController\getLanguageService
‪getLanguageService()
Definition: LoginController.php:450
‪TYPO3\CMS\Backend\Controller\LoginController\provideCustomLoginStyling
‪provideCustomLoginStyling()
Definition: LoginController.php:253
‪TYPO3\CMS\Backend\Controller\LoginController\$view
‪StandaloneView $view
Definition: LoginController.php:96
‪TYPO3\CMS\Backend\Controller\LoginController\isLoginInProgress
‪isLoginInProgress(ServerRequestInterface $request)
Definition: LoginController.php:426
‪TYPO3\CMS\Backend\Template\PageRendererBackendSetupTrait
Definition: PageRendererBackendSetupTrait.php:45
‪TYPO3\CMS\Core\FormProtection\BackendFormProtection
Definition: BackendFormProtection.php:75
‪TYPO3\CMS\Backend\Controller\LoginController\$redirectUrl
‪string $redirectUrl
Definition: LoginController.php:67
‪TYPO3\CMS\Backend\Controller\LoginController\$loginProviderIdentifier
‪string $loginProviderIdentifier
Definition: LoginController.php:78
‪TYPO3\CMS\Core\Localization\Locales
Definition: Locales.php:36
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication\getCookieName
‪static getCookieName()
Definition: BackendUserAuthentication.php:1800
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Backend\Controller\LoginController\requestTokenAction
‪requestTokenAction(ServerRequestInterface $request)
Definition: LoginController.php:145
‪TYPO3\CMS\Backend\Controller\LoginController\getSystemNews
‪getSystemNews()
Definition: LoginController.php:400
‪TYPO3\CMS\Backend\LoginProvider\LoginProviderResolver
Definition: LoginProviderResolver.php:37
‪TYPO3\CMS\Core\Page\PageRenderer
Definition: PageRenderer.php:44
‪TYPO3\CMS\Backend\Controller\LoginController\getCurrentRequest
‪getCurrentRequest()
Definition: LoginController.php:165
‪TYPO3\CMS\Core\Security\RequestToken
Definition: RequestToken.php:26
‪TYPO3\CMS\Backend\Controller\LoginController\$loginRefresh
‪bool $loginRefresh
Definition: LoginController.php:86
‪TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException
Definition: RouteNotFoundException.php:21
‪TYPO3\CMS\Core\Context\SecurityAspect
Definition: SecurityAspect.php:30
‪TYPO3\CMS\Backend\Controller\LoginController\createLoginLogoutForm
‪createLoginLogoutForm(ServerRequestInterface $request)
Definition: LoginController.php:284
‪TYPO3\CMS\Backend\Controller\LoginController\$request
‪ServerRequestInterface $request
Definition: LoginController.php:101
‪TYPO3\CMS\Backend\Routing\RouteRedirect
Definition: RouteRedirect.php:30
‪TYPO3\CMS\Backend\Routing\UriBuilder
Definition: UriBuilder.php:44
‪TYPO3\CMS\Backend\Controller\LoginController\formAction
‪formAction(ServerRequestInterface $request)
Definition: LoginController.php:121
‪TYPO3\CMS\Core\Configuration\Features
Definition: Features.php:56
‪TYPO3\CMS\Backend\Controller\LoginController\appendLoginProviderCookie
‪appendLoginProviderCookie(ServerRequestInterface $request, NormalizedParams $normalizedParams, ResponseInterface $response)
Definition: LoginController.php:174
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Backend\Controller\LoginController\renderHtmlViaLoginProvider
‪renderHtmlViaLoginProvider()
Definition: LoginController.php:332
‪TYPO3\CMS\Backend\Controller\LoginController\__construct
‪__construct(protected readonly Typo3Information $typo3Information, protected readonly EventDispatcherInterface $eventDispatcher, protected readonly PageRenderer $pageRenderer, protected readonly UriBuilder $uriBuilder, protected readonly Features $features, protected readonly Context $context, protected readonly LoginProviderResolver $loginProviderResolver, protected readonly ExtensionConfiguration $extensionConfiguration, protected readonly BackendEntryPointResolver $backendEntryPointResolver, protected readonly FormProtectionFactory $formProtectionFactory, protected readonly Locales $locales,)
Definition: LoginController.php:103
‪TYPO3\CMS\Core\Http\NormalizedParams\isHttps
‪bool isHttps()
Definition: NormalizedParams.php:340
‪TYPO3\CMS\Backend\Controller\LoginController\refreshAction
‪refreshAction(ServerRequestInterface $request)
Definition: LoginController.php:132
‪TYPO3\CMS\Backend\Controller\LoginController\init
‪init(ServerRequestInterface $request)
Definition: LoginController.php:197
‪TYPO3\CMS\Core\Http\PropagateResponseException
Definition: PropagateResponseException.php:47
‪TYPO3\CMS\Backend\Controller\LoginController\$submitValue
‪string $submitValue
Definition: LoginController.php:92
‪TYPO3\CMS\Core\Http\RedirectResponse
Definition: RedirectResponse.php:30
‪TYPO3\CMS\Core\Security\RequestToken\PARAM_NAME
‪const PARAM_NAME
Definition: RequestToken.php:28
‪TYPO3\CMS\Backend\Controller\LoginController\redirectToUrl
‪redirectToUrl()
Definition: LoginController.php:439
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory
Definition: FormProtectionFactory.php:43
‪TYPO3\CMS\Fluid\View\StandaloneView
Definition: StandaloneView.php:30
‪TYPO3\CMS\Core\Http\JsonResponse
Definition: JsonResponse.php:28
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Backend\Controller\LoginController\provideRequestTokenJwt
‪provideRequestTokenJwt()
Definition: LoginController.php:444
‪TYPO3\CMS\Backend\Template\PageRendererBackendSetupTrait\setUpBasicPageRendererForBackend
‪setUpBasicPageRendererForBackend(PageRenderer $pageRenderer, ExtensionConfiguration $extensionConfiguration, ServerRequestInterface $request, LanguageService $languageService,)
Definition: PageRendererBackendSetupTrait.php:49
‪TYPO3\CMS\Backend\Attribute\AsController
Definition: AsController.php:25
‪TYPO3\CMS\Backend\Controller\LoginController\getBackendUserAuthentication
‪getBackendUserAuthentication()
Definition: LoginController.php:455
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Backend\Routing\RouteRedirect\createFromRequest
‪static createFromRequest(ServerRequestInterface $request)
Definition: RouteRedirect.php:58
‪TYPO3\CMS\Core\Security\RequestToken\create
‪static create(string $scope)
Definition: RequestToken.php:43
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Backend\Controller\LoginController
Definition: LoginController.php:61
‪TYPO3\CMS\Backend\Controller
Definition: AboutController.php:18
‪TYPO3\CMS\Core\Routing\BackendEntryPointResolver
Definition: BackendEntryPointResolver.php:29
‪TYPO3\CMS\Backend\Controller\LoginController\checkRedirect
‪checkRedirect(ServerRequestInterface $request)
Definition: LoginController.php:355
‪TYPO3\CMS\Core\Http\NormalizedParams
Definition: NormalizedParams.php:38