---
title: "Backend login form API"
manual: "TYPO3 Explained"
version: "main"
permalink: "https://docs.typo3.org/permalink/t3coreapi:login-provider@main"
source: "ApiOverview/Backend/LoginProvider.rst"
rendered: "2026-09-19T06:56:03+00:00"
---

# Backend login form API {#login-provider}

## Registering a login provider {#login-provider-registration}

The concept of the backend login is based on "login providers".

A login provider can be registered within your `config/system/settings.php`
or `config/system/additional.php`  like this:

**config/system/additional.php | typo3conf/system/additional.php**

```php
<?php

use MyVendor\MyExtension\LoginProvider\CustomLoginProvider;

$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['backend']['loginProviders'][1433416020]
  = [
    'provider' => CustomLoginProvider::class,
    'sorting' => 50,
    'iconIdentifier' => 'actions-key',
    'label' => 'backend.messages:login.link',
  ];

```

The settings are defined as:

-   **`provider`**

    The login provider class name, which must implement
    `\TYPO3\CMS\Backend\LoginProvider\LoginProviderInterface`.

-   **`sorting`**

    The sorting is important for the ordering of the links to the possible
    login providers on the login screen.

-   **`iconIdentifier`**

    Accepts any icon identifier that is available in the Icon Registry.

-   **`label`**

    The label for the login provider link on the login screen.

For a new login provider you have to register a **new key** \- by best practice
the current unix timestamp - in
`$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['backend']['loginProviders']`.

If your login provider extends another one, you may only overwrite necessary
settings. An example would be to extend an existing provider and
replace its registered `provider` class with your custom class.

**config/system/additional.php | typo3conf/system/additional.php**

```php
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['backend']['loginProviders'][1433416020]['provider'] =
    \MyVendor\MyExtension\LoginProvider\CustomProviderExtendingUsernamePasswordLoginProvider::class
```

## `LoginProviderInterface` {#login-provider-interface}

-   **interface LoginProviderInterface**

    -   *Fully qualified name:* `\TYPO3\CMS\Backend\LoginProvider\LoginProviderInterface`

    Interface for Backend Login providers

    -   **modifyView(\\Psr\\Http\\Message\\ServerRequestInterface $request, \\TYPO3\\CMS\\Core\\View\\ViewInterface $view)**

        Interface to render the backend login view.

        See UsernamePasswordLoginProvider on how this can be used.

        -   *param $request:* the request
        -   *param $view:* the view
        -   *Return description:* Template file to render

        *Returns:* `string`

Consumers of `LoginProviderInterface`
should implement the `modifyView()` method. See the example below.

An implementation of `LoginProviderInterface` could
look like this:

**EXT:my_extension/Classes/Login/MyLoginProvider.php**

```php
<?php

namespace MyVendor\MyExtension\Login;

use Psr\Http\Message\ServerRequestInterface;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
use TYPO3\CMS\Backend\LoginProvider\LoginProviderInterface;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\View\ViewInterface;
use TYPO3\CMS\Fluid\View\FluidViewAdapter;

#[Autoconfigure(public: true)]
final readonly class MyLoginProvider implements LoginProviderInterface
{
  public function __construct(
    private PageRenderer $pageRenderer,
  ) {}

  public function modifyView(ServerRequestInterface $request, ViewInterface $view): string
  {
    $this->pageRenderer->addJsFile('someFile');
    // Custom login provider implementations can add custom fluid lookup paths.
    if ($view instanceof FluidViewAdapter) {
      $templatePaths = $view->getRenderingContext()->getTemplatePaths();
      $templateRootPaths = $templatePaths->getTemplateRootPaths();
      $templateRootPaths[] = 'EXT:my_extension/Resources/Private/Templates';
      $templatePaths->setTemplateRootPaths($templateRootPaths);
    }
    $view->assign('Some Variable', 'some value');
    return 'Login/MyLoginForm';
  }
}

```

The default implementation in `UsernamePasswordLoginProvider`
is a good example. Extensions that need to configure additional template, layout or
partial lookup paths can extend them, see lines 23-28 in the example above.

## The view {#login-provider-view}

The name of the template must be returned by the `modifyView()` method of the
login provider. Variables can be assigned to the view supplied as
second parameter.

The template file must only contain the form fields, not the form-tag.
Later on, the view renders the complete login screen.

View requirements:

-   The template must use the `Login`-layout provided by the
    Core `<f:layout name="Login">`.
-   Form fields must be provided within the section
    `<f:section name="loginFormFields">`.

**EXT:my_sitepackage/Resources/Private/Templates/MyLoginForm.fluid.html**

```html
<f:layout name="Login" />
<f:section name="loginFormFields">
  <div class="form-group t3js-login-openid-section" id="t3-login-openid_url-section">
    <div class="input-group">
      <input
        type="text"
        id="openid_url"
        name="openid_url"
        value="{presetOpenId}"
        autofocus="autofocus"
        placeholder="{f:translate(key: 'openId', extensionName: 'openid')}"
        class="form-control input-login t3js-clearable t3js-login-openid-field"
      >
      <div class="input-group-addon">
        <span class="fa fa-openid"></span>
      </div>
    </div>
  </div>
</f:section>

```

## Examples {#login-provider-examples}

Within the Core you can find the standard implementation in the system extension
`backend`:

See class [EXT:backend/Classes/LoginProvider/UsernamePasswordLoginProvider.php (GitHub)](https://github.com/typo3/typo3/blob/main/typo3/sysext/backend/Classes/LoginProvider/UsernamePasswordLoginProvider.php)
with its template [EXT:backend/Resources/Private/Templates/Login/UserPassLoginForm.fluid.html (GitHub)](https://github.com/typo3/typo3/blob/main/typo3/sysext/backend/Resources/Private/Templates/Login/UserPassLoginForm.fluid.html).
