WordPress Login-Seite anpassen: Der komplette Leitfaden (2026)

WordPress Login-Seite anpassen: Der komplette Leitfaden (2026)

Zuletzt überprüft: 14. Oktober 2026
20 Min. Lesezeit
Leitfaden
Sicherheitsauditor
Full-Stack-Entwickler

Der Standard-Anmeldebildschirm von WordPress (wp-login.php) ist in drei Sekunden erkennbar: grauer Hintergrund, WordPress-Logo, generisches Formular. Für einen Hobby-Blog ist das in Ordnung. Für einen Shop, ein Kundenportal oder ein Agenturprojekt unter der Marke des Kunden ist es ein Branding-Fehler. Redakteure melden sich täglich an, und ihr erster Eindruck ist nicht die Startseite, sondern dieser Bildschirm.

Dieser Leitfaden zeigt, wie Sie das Login ausschließlich mit WordPress-Hooks an die Marke anpassen: login_enqueue_scripts, die Logo-Filter login_headerurl und login_headertext, login_message, generische Fehlermeldungen und die Entscheidung zwischen Must-use-Plugin und Child-Theme. Alle Hooks und Versionsangaben sind gegen den Quellcode von WordPress 7.1 geprüft. Für Härtung, die über das Aussehen hinausgeht, siehe unseren Leitfaden zur robusten Absicherung.

#Was WordPress auf wp-login.php lädt

Bevor Sie das Logo austauschen, lohnt ein Blick darauf, was der Kern bei einer Anfrage an wp-login.php tut:

  1. Er lädt wp-admin/css/login.css und die abhängigen Dashboard-Stile (Buttons, Formulare).
  2. Er löst login_enqueue_scripts aus. Hier binden Sie eigenes CSS und JS ein, genau wie mit wp_enqueue_scripts im Frontend.
  3. Er rendert den Kopf mit dem Logo-Link (standardmäßig auf wordpress.org), das Formular, die Links für vergessene Passwörter und Registrierung sowie die Fußzeile.
  4. Bei einem Validierungsfehler hängt er das Wackel-Skript an und zeigt die Meldung aus dem Filter login_errors.
  5. Die Filter login_message und login_messages setzen HTML über das Formular (Hinweis nach dem Abmelden, Wartungshinweis, SSO-Banner).

Die wichtigste Folge: Die Login-Seite läuft nicht durch die Frontend-Pipeline des Themes. header.php, Vorlagen eines Block-Themes und die meisten Callbacks an wp_enqueue_scripts greifen dort nicht. Deshalb gibt es eine eigene Enqueue-Aktion, und deshalb brauchen die Login-Stile eine eigene Datei. Regeln, die nur in der style.css des Themes stehen, erreichen wp-login.php nie.

Die zweite Folge: Ein WordPress-Update kann Selektoren, die Reihenfolge der Skripte oder das Markup des Formulars ändern (zusätzliche Felder eines 2FA-Plugins zum Beispiel). Branding auf Basis von Hooks übersteht das Update, ein gepatchtes wp-login.php im Kern nicht.

#Eigenes CSS für die WordPress-Login-Seite laden

Der graue Standardhintergrund (#f0f0f1 in der aktuellen login.css) passt selten zur Marke. Legen Sie eine Datei style-login.css im Theme an und laden Sie sie nur auf der Anmeldeseite, mit Versionsnummer, damit Browser nach einem Deploy nicht die alte Fassung aus dem Cache nehmen:

function wppoland_login_stylesheet() {
	wp_enqueue_style(
		'wppoland-login',
		get_stylesheet_directory_uri() . '/style-login.css',
		array(),
		wp_get_theme()->get( 'Version' )
	);
}
add_action( 'login_enqueue_scripts', 'wppoland_login_stylesheet' );

Beispiel style-login.css:

body.login {
	background-color: #0d1117;
	display: flex;
	align-items: center;
	justify-content: center;
	min-height: 100vh;
	font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

.login form {
	background: #161b22;
	border: 1px solid #30363d;
	box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
	border-radius: 12px;
	padding: 40px;
}

.login label {
	color: #c9d1d9;
	font-size: 14px;
	font-weight: 500;
}

.login input[type="text"],
.login input[type="password"] {
	background: #0d1117;
	border: 1px solid #30363d;
	border-radius: 6px;
	color: #c9d1d9;
	padding: 12px 16px;
	font-size: 14px;
}

.login input[type="text"]:focus,
.login input[type="password"]:focus {
	border-color: #58a6ff;
	box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.4);
}

.wp-core-ui .button-primary {
	background: #238636;
	border-color: rgba(27, 31, 35, 0.15);
	border-radius: 6px;
	padding: 12px 24px;
	font-size: 14px;
	font-weight: 600;
	text-shadow: none;
	box-shadow: none;
}

.wp-core-ui .button-primary:hover,
.wp-core-ui .button-primary:focus {
	background: #2ea043;
}

.login #nav,
.login #backtoblog {
	text-align: center;
}

.login #nav a,
.login #backtoblog a {
	color: #8b949e;
}

.login #nav a:hover,
.login #backtoblog a:hover {
	color: #58a6ff;
}

Praktische Regeln für Login-CSS:

  • Zielen Sie auf Klassen, die WordPress tatsächlich ausgibt: body.login, #login, .login form, .wp-core-ui .button-primary, #login_error, .message.
  • Blenden Sie #nav und #backtoblog nicht ohne Absprache mit dem Kunden aus. Redakteure verlieren sonst den Weg zurück zum Frontend, und die Passwort-Wiederherstellung wirkt kaputt.
  • Vermeiden Sie display: none auf Formularfeldern. Ein 2FA- oder Passkey-Plugin fügt eigene Felder hinzu, und per CSS versteckt sehen sie aus wie ein defektes Login.
  • Prüfen Sie den Kontrast (WCAG) bei Fehlermeldungen und Labels. Dunkler Hintergrund mit grauem Text fällt in Barrierefreiheits-Audits oft durch. Entfernen Sie den Fokusrahmen nicht ersatzlos: Im Beispiel oben übernimmt ein deutlich sichtbarer box-shadow diese Rolle.

Schriften des Kunden laden Sie hier oder hosten sie lokal im Theme. Eine dritte Domain auf dem Login-Bildschirm ist eine überflüssige Anfrage und ein weiterer DNS-Ausfallpunkt.

#WordPress-Login-Logo ändern

WordPress hat keinen Filter, der die Logo-Datei austauscht. Das übliche Muster ist CSS auf #login h1 a als Hintergrundbild plus zwei Filter für die Attribute des Links.

function wppoland_login_logo() {
	$logo = get_stylesheet_directory_uri() . '/images/kunden-logo.svg';
	?>
	<style type="text/css">
		#login h1 a,
		.login h1 a {
			background-image: url(<?php echo esc_url( $logo ); ?>);
			height: 65px;
			width: 100%;
			max-width: 320px;
			background-size: contain;
			background-repeat: no-repeat;
			background-position: center;
			padding-bottom: 30px;
		}

		@media (max-width: 768px) {
			#login h1 a,
			.login h1 a {
				height: 50px;
				max-width: 280px;
			}
		}
	</style>
	<?php
}
add_action( 'login_enqueue_scripts', 'wppoland_login_logo' );

esc_url() auf dem Pfad ist Pflicht, auch wenn die URL aus get_stylesheet_directory_uri() stammt. Verwenden Sie SVG oder PNG mit Transparenz. Ein JPEG mit weißem Rand wirkt auf einem dunklen Formular wie ein Aufkleber. Die Media Query verkleinert das Logo auf schmalen Bildschirmen, damit es das Formular nicht nach unten drückt.

Der Standardlink des Logos führt zu wordpress.org. Leiten Sie ihn auf die Startseite um und setzen Sie den zugänglichen Linktext auf den Namen der Website:

function wppoland_login_logo_url() {
	return home_url( '/' );
}
add_filter( 'login_headerurl', 'wppoland_login_logo_url' );

function wppoland_login_logo_url_title() {
	return get_bloginfo( 'name' );
}
add_filter( 'login_headertext', 'wppoland_login_logo_url_title' );

login_headertext ersetzt login_headertitle, das seit WordPress 5.2 als veraltet markiert ist. Ältere Snippets im Netz verwenden es noch.

Bei Installationen mit eigener Dashboard-Domain (cms.kunde.de neben www.kunde.de) zeigt home_url() weiter auf das öffentliche Frontend, was meist gewünscht ist. Soll das Logo zu einer internen Dokumentation oder zum Identity Provider führen, geben Sie eine vollständige HTTPS-URL zurück und testen Sie im privaten Fenster.

#Meldung über dem WordPress-Login-Formular anzeigen

Der Filter login_message setzt HTML über das Formular. Typische Einsätze in Produktion:

  • Ein Wartungshinweis („Login außerhalb des VPN heute Abend gesperrt“).
  • Ein Hinweis für Redakteure („Bitte das Firmenkonto verwenden, kein privates“).
  • Ein Banner nach dem Abmelden oder nach dem Zurücksetzen des Passworts (WordPress setzt dort auch eigene Meldungsklassen).
  • Ein Link zum SSO, wenn der Identity Provider neben klassischen Passwörtern läuft.
/**
 * Meldung über dem Login-Formular.
 *
 * @param string $message Vorhandenes HTML.
 * @return string
 */
function wppoland_login_message( $message ) {
	$notice = '<p class="message">' . esc_html__(
		'Nur für Konten des Redaktionsteams. Verdacht auf ein geleaktes Passwort bitte an die IT melden.',
		'wppoland'
	) . '</p>';

	return $notice . $message;
}
add_filter( 'login_message', 'wppoland_login_message' );

Hinweise zur Umsetzung:

  • Escapen Sie den Text (esc_html__) oder bauen Sie das Markup mit wp_kses_post, wenn ein Link nötig ist.
  • Ersetzen Sie $message nicht blind. WordPress legt dort eigene Meldungen ab (nach loggedout=true zum Beispiel). Stellen Sie Ihren Text voran oder filtern Sie abhängig von der Anfrage.
  • Die Klasse .message ist in login.css bereits gestaltet. Ihre style-login.css sollte sie respektieren (Textfarbe, linker Rand), sonst verschwindet das Banner im Hintergrund.

Für Texte, die von der Aktion abhängen (login, lostpassword, rp), prüfen Sie $_GET['action'], statt denselben Hinweis bei der Passwort-Wiederherstellung und beim 2FA-Schritt zu zeigen.

#Eigene Inhalte unter dem Login-Formular einfügen

Für einen Support-Hinweis unter dem Formular eignet sich die Aktion login_footer:

function wppoland_login_footer_content() {
	?>
	<div class="login-footer-content">
		<p><?php echo esc_html__( 'Probleme bei der Anmeldung? Wenden Sie sich an den Support Ihrer Agentur.', 'wppoland' ); ?></p>
		<p>&copy; <?php echo esc_html( wp_date( 'Y' ) . ' ' . get_bloginfo( 'name' ) ); ?></p>
	</div>
	<?php
}
add_action( 'login_footer', 'wppoland_login_footer_content' );

Die Gestaltung von .login-footer-content gehört in die style-login.css, nicht in einen eingebetteten <style>-Block. So bleiben alle Login-Regeln in einer Datei, die Sie versionieren.

#Markenfarben des Kunden per CSS-Variablen setzen

Agenturen, die dieselbe Login-Vorlage für mehrere Kunden einsetzen, halten die Farben am besten als CSS-Variablen an einer Stelle:

function wppoland_agency_branding() {
	$primary   = sanitize_hex_color( '#0073aa' ); // Primärfarbe des Kunden
	$secondary = sanitize_hex_color( '#005177' ); // Sekundärfarbe
	?>
	<style type="text/css">
		:root {
			--brand-primary: <?php echo esc_attr( $primary ); ?>;
			--brand-secondary: <?php echo esc_attr( $secondary ); ?>;
		}

		body.login {
			background: linear-gradient(135deg, var(--brand-primary) 0%, var(--brand-secondary) 100%);
		}

		.wp-core-ui .button-primary {
			background: var(--brand-primary);
			border-color: var(--brand-primary);
		}

		.wp-core-ui .button-primary:hover {
			background: var(--brand-secondary);
			border-color: var(--brand-secondary);
		}
	</style>
	<?php
}
add_action( 'login_enqueue_scripts', 'wppoland_agency_branding' );

Kommen die Farben später aus einer Option oder dem Customizer, sorgt sanitize_hex_color() (seit WordPress 3.4 in formatting.php, also auch auf der Login-Seite verfügbar) dafür, dass nur gültige Hex-Werte im CSS landen.

#Login-Fehlermeldungen in WordPress verallgemeinern

Die Standardmeldung bei einem falschen Passwort kann verraten, dass ein Benutzer mit diesem Namen existiert. Das erleichtert die Enumeration von Konten vor einem Brute-Force-Angriff. Der Filter login_errors gibt stattdessen einen generischen Text zurück:

function wppoland_login_errors() {
	return __( 'Anmeldung fehlgeschlagen. Bitte prüfen Sie Ihre Zugangsdaten.', 'wppoland' );
}
add_filter( 'login_errors', 'wppoland_login_errors' );

Das erschwert die Aufklärung durch Angreifer. Es ist keine Firewall, kein Rate Limiting und kein 2FA. Sie brauchen weiterhin:

  • Begrenzung der Anmeldeversuche auf Server, WAF oder mit einem gepflegten Plugin (mehr dazu im Leitfaden zum Login absichern),
  • starke Passwörter und möglichst einen zweiten Faktor (TOTP-App, Hardware-Schlüssel),
  • aktuelle Versionen von WordPress, Themes und Plugins,
  • Zugriffsbeschränkung für wp-admin und XML-RPC, wo die Firmenrichtlinie es erlaubt (VPN, IP-Allowlist, HTTP-Auth auf Staging).

In vielen Anleitungen tauchen eigene Login-Sperren per Transient auf login_init und Nonce-Prüfungen im Filter authenticate auf. Davon raten wir ab. login_init läuft bei jedem Aufruf von wp-login.php, also auch beim Zurücksetzen des Passworts, und ein wp_die() dort sperrt genau diesen Weg. Der Filter authenticate prüft auch Anmeldungen über XML-RPC, Anwendungspasswörter (wp_authenticate_application_password hängt laut default-filters.php mit Priorität 20 an diesem Filter) und wp_signon() aus Plugins wie WooCommerce, die kein solches Nonce-Feld mitsenden. Eine Nonce-Prüfung mit Priorität 30 bricht diese Anmeldewege.

Ebenso häufig: „Wir verstecken das Login, dann ist es sicher“. Warum das nicht trägt:

  1. Security through obscurity: Bots und Scanner kennen die Standardpfade. Eine geänderte URL ohne echte Zugriffskontrolle zerstört vor allem die Lesezeichen der Redakteure.
  2. CSS versteckt serverseitig nichts: display: none auf einem Login-Link im Menü entfernt den Endpunkt nicht. wp-login.php und wp-admin antworten weiter.
  3. Der Filter login_url ändert nur die Links, die WordPress erzeugt, nicht den Endpunkt selbst. Ein echter Umzug des Logins braucht Server-Konfiguration oder ein gepflegtes Plugin, und danach Tests für Passwort-Reset, WooCommerce „Mein Konto“, REST und Cron.
  4. REST- und XML-RPC-Antworten können die Existenz von Benutzern unabhängig vom Branding des Bildschirms verraten.

Branding des Logins und Sicherheit sind zwei getrennte Spuren. White-Label verbessert UX und Vertrauen. Kontoschutz entsteht durch Berechtigungen, Rate Limits, 2FA und Updates.

#Two-Factor-Felder auf der WordPress-Login-Seite gestalten

2FA selbst in der functions.php zu bauen ist das falsche Projekt. Nutzen Sie ein gepflegtes Plugin, zum Beispiel Two Factor aus dem WordPress.org-Verzeichnis (Version 0.17.0, laut Verzeichnis-API im Oktober 2026 über 100.000 aktive Installationen), und passen Sie dessen Felder an das Branding an.

Klassen, die dieses Plugin im zweiten Anmeldeschritt tatsächlich ausgibt (geprüft im Code der Version 0.17.0):

  • .two-factor-prompt für den Absatz mit der Anleitung,
  • input.authcode (mit id="authcode") für den TOTP-Code, den E-Mail-Code und den Backup-Code; das Feld trägt inputmode="numeric" und autocomplete="one-time-code", überschreiben Sie diese Attribute also nicht per Skript, sonst schlägt das Telefon den Code aus SMS oder Passwortmanager nicht mehr vor,
  • .backup-methods-wrap für die Links zu alternativen Methoden,
  • .two-factor-email-resend für den Button, der den E-Mail-Code erneut sendet.
.login .two-factor-prompt {
	color: #c9d1d9;
}

.login input.authcode {
	background: #0d1117;
	border: 1px solid #30363d;
	color: #c9d1d9;
	letter-spacing: 0.2em;
	text-align: center;
}

.login .backup-methods-wrap a {
	color: #c9d1d9;
}

Selektoren wie .two-factor-methods oder .passkey-button, die in älteren Anleitungen kursieren, gibt es im aktuellen Plugin-Code nicht, und Regeln dafür greifen nie. Andere 2FA- und Passkey-Plugins haben eigenes Markup: Lesen Sie deren Selektoren im jeweiligen Code nach.

Wenn Administratoren ohne eingerichtetes 2FA nach dem Login direkt zur Einrichtung geschickt werden sollen, nutzen Sie den Filter login_redirect mit der öffentlichen Methode des Plugins:

function wppoland_2fa_setup_redirect( $redirect_to, $requested_redirect_to, $user ) {
	if ( ! $user instanceof WP_User || ! class_exists( 'Two_Factor_Core' ) ) {
		return $redirect_to;
	}

	if ( user_can( $user, 'manage_options' ) && ! Two_Factor_Core::is_user_using_two_factor( $user->ID ) ) {
		return admin_url( 'profile.php#two-factor-options' );
	}

	return $redirect_to;
}
add_filter( 'login_redirect', 'wppoland_2fa_setup_redirect', 10, 3 );

Two_Factor_Core::is_user_using_two_factor() und der Anker #two-factor-options im Profil stammen aus dem Plugin-Code. user_can() prüft den übergebenen Benutzer; current_user_can() wäre an dieser Stelle falsch, weil der aktuelle Benutzer während des Filters noch nicht gesetzt ist. Ein echter Zwang ist das nicht, nur ein Hinweis beim Login.

#Shake-Effekt beim WordPress-Login entfernen

Wenn die Anmeldung fehlschlägt, wackelt das Formular. Manche Kunden finden das unprofessionell.

Das Snippet, das die meisten Anleitungen noch kopieren, remove_action( 'login_head', 'wp_shake_js', 12 ), bewirkt seit WordPress 5.4 nichts mehr. Der Kern hängt wp_shake_js inzwischen an login_footer, und zwar nur bedingt, innerhalb von login_header(). Das zeigt wp-login.php im Repository wordpress-develop; der Branch 5.3 nutzte noch login_head. Die stabile Methode ist der Filter shake_error_codes, verfügbar seit 3.0: Eine leere Liste von Fehlercodes bedeutet keine Animation.

add_filter( 'shake_error_codes', '__return_empty_array' );

Der Filter ist öffentliche API und hängt weder von der Priorität noch davon ab, über welchen Hook der Kern das Skript gerade ausgibt.

#Plugins für die WordPress-Login-Seite im Vergleich

Wer das Login nicht im Code pflegen will, findet im Verzeichnis auf WordPress.org mehrere Plugins. Stand laut Plugin-API von WordPress.org am 14. Oktober 2026:

PluginVersionAktive InstallationenSchwerpunkt
LoginPress6.2.5200.000+Visueller Designer für wp-login.php
Custom Login Page Customizer2.5.490.000+Gestaltung im Customizer
Theme My Login7.3.150.000+Login-Seiten im Frontend

Das früher oft genannte Plugin Login Designer ist im Verzeichnis inzwischen geschlossen und sollte nicht mehr neu installiert werden. Stapeln Sie kein Plugin auf die Hooks aus diesem Leitfaden: Zwei Quellen, die beide #login h1 a gestalten, überschreiben sich gegenseitig. Entscheiden Sie sich für Code oder ein Plugin.

#Must-use-Plugin oder Child-Theme für den Login-Code

Wo soll der Code liegen? Es gibt zwei sinnvolle Orte und einen falschen.

Child-Theme (functions.php und style-login.css)

  • Vorteile: Logo und Farben reisen mit dem Frontend-Design; der Designer ändert Dateien in einem Repository; Versionierung über Version in der style.css.
  • Nachteile: Ein Theme-Wechsel (Störung, A/B-Test, Umstieg auf ein Block-Theme) schaltet das Login-Branding ab. Auf Multisite mit unterschiedlichen Themes je Website muss der Code dupliziert oder nach oben verlagert werden, siehe unsere Multisite-Architektur.

Must-use-Plugin (wp-content/mu-plugins/wppoland-login-branding.php)

  • Vorteile: Läuft unabhängig vom aktiven Theme, ideal für Agentur-Netzwerke und Installationen, deren Theme wechselt; schwer versehentlich im Dashboard zu deaktivieren.
  • Nachteile: Assets (Logo, CSS) laden Sie aus dem Verzeichnis des Plugins (plugin_dir_url( __FILE__ )); der Deploy von Must-use-Plugins fällt in Workflows, die nur das Theme ausrollen, gern unter den Tisch.

Der falsche Ort: Änderungen in wp-admin/ oder ein Patch an wp-login.php im Kern. Beides verschwindet beim nächsten Update. Meiden Sie auch Snippet-Plugins, die PHP ohne Versionskontrolle in der Datenbank speichern: Bei der Migration von Staging zu Produktion gehen die Snippets verloren oder werden doppelt angelegt.

<?php
/**
 * Plugin Name: WPPoland Login Branding
 * Description: White-Label für wp-login.php unabhängig vom Theme.
 * Author: wppoland.com
 */

defined( 'ABSPATH' ) || exit;

add_action( 'login_enqueue_scripts', function () {
	wp_enqueue_style(
		'wppoland-login',
		plugin_dir_url( __FILE__ ) . 'assets/style-login.css',
		array(),
		'2026.10.14'
	);
} );

add_filter( 'login_headerurl', function () {
	return home_url( '/' );
} );

add_filter( 'login_headertext', function () {
	return get_bloginfo( 'name' );
} );

Entscheidungsregel fürs Briefing: Ist das Login-Branding Teil des Kundenprodukts (Markenfarben, Kampagnenlogo), gehört es ins Child-Theme. Ist es ein Agenturstandard auf vielen Installationen (dasselbe Agenturlogo auf allen Staging-Umgebungen, generische Fehler, kein Wackeln), gehört es in ein Must-use-Plugin oder ein gemeinsames Composer-Paket, das auf alle Umgebungen ausgerollt wird.

#Login-Seiten von WooCommerce und Mitgliedschafts-Plugins anpassen

Die Kontoseiten von WooCommerce und die Login-Blöcke im Checkout haben ein anderes Markup als wp-login.php. CSS für den Login-Bildschirm verändert die Formulare unter my-account nicht. Entweder bleiben die Standardformulare von Woo, oder Sie laden auf diesen Templates ein eigenes Stylesheet. Wer beides in style-login.css mischt, hinterlässt tote Regeln und verwirrt den nächsten Entwickler.

Dieselbe Trennung gilt für LearnDash, MemberPress und vergleichbare Produkte: Erst klären, über welche Adresse sich Kunden tatsächlich anmelden, dann genau diese Oberfläche gestalten. Ein typischer Agenturfehler ist ein polierter wp-login.php, während Kunden nur ein Modal im Frontend sehen, das in einem iframe weiterhin das WordPress-Logo zeigt.

#Login-Seite nach WordPress-Core-Updates prüfen

Größere WordPress-Releases ändern gelegentlich das Login-Markup oder das Standard-CSS. Nach dem Core-Update auf Staging:

  1. Wenn etwas komisch aussieht, das Login-HTML mit der Version vor dem Update vergleichen.
  2. Logogröße erneut prüfen; neue Standardhöhen können SVGs abschneiden.
  3. Wenn Sie den Shake-Effekt deaktiviert haben, prüfen, ob der Filter shake_error_codes weiterhin greift.
  4. 2FA-Felder erneut testen, falls das Plugin im selben Zeitraum aktualisiert wurde.

Koppeln Sie die Version des Stylesheets an die Theme- oder Plugin-Version, damit Browser nach einer Kontrastkorrektur keine veraltete style-login.css behalten.

#Welche Login-Hooks WordPress seit welcher Version bietet

Die Tabelle stammt aus den @since-Angaben in src/wp-login.php im Repository wordpress-develop (Oktober 2026, aktuelle Version WordPress 7.1.3). Sie hilft, wenn ein Kunde eine alte Installation betreibt oder ein Forum-Snippet einen Hook nutzt, den es noch nicht gibt oder der bereits veraltet ist.

HookTypSeitZweck
login_headerurlFilter2.1.0URL des Logo-Links
login_messageFilter2.1.0HTML über dem Formular
login_errorsFilter2.1.0Fehlertext
login_messagesFilter2.5.0Informationsmeldungen
login_redirectFilter3.0.0Weiterleitungsziel nach dem Login
shake_error_codesFilter3.0.0Fehlercodes, die das Formular wackeln lassen
login_enqueue_scriptsAktion3.1.0CSS und JS der Login-Seite
login_footerAktion3.1.0Ausgabe in der Fußzeile
login_initAktion3.2.0Beginn der Verarbeitung der Anfrage
login_body_classFilter3.5.0Klassen des body-Elements
login_headerAktion4.6.0Ausgabe direkt nach dem öffnenden body-Tag
login_titleFilter4.9.0Inhalt des title-Tags
login_link_separatorFilter4.9.0Trenner zwischen den Links unter dem Formular
login_headertextFilter5.2.0Linktext des Logos
login_site_html_linkFilter5.7.0Link zurück zur Website in der Fußzeile
login_display_language_dropdownFilter5.9.0ob die Sprachauswahl erscheint
login_language_dropdown_argsFilter5.9.0Argumente der Sprachliste

login_headertitle (seit 2.1.0) ist seit 5.2.0 veraltet und läuft über apply_filters_deprecated. Mit aktivem WP_DEBUG hinterlässt er einen Hinweis im Log. Nutzt ein Kunden-Theme ihn noch, stellen Sie auf login_headertext um.

#Titel, Body-Klasse und Sprachauswahl auf wp-login.php ändern

Vier Filter aus der Tabelle erledigen kleine Wünsche aus dem Briefing, ohne CSS anzufassen:

// Kürzerer Tab-Titel: Name des Bildschirms und Name der Website.
add_filter( 'login_title', function ( $login_title, $title ) {
	return $title . ' | ' . get_bloginfo( 'name', 'display' );
}, 10, 2 );

// Eigene Klasse am body, damit Login-Regeln nicht mit anderen Stylesheets kollidieren.
add_filter( 'login_body_class', function ( $classes ) {
	$classes[] = 'wppoland-login';
	return $classes;
} );

// Der Link in der Fußzeile führt zur Hilfeseite statt zur Startseite.
add_filter( 'login_site_html_link', function () {
	return sprintf(
		'<a href="%s">%s</a>',
		esc_url( home_url( '/hilfe/' ) ),
		esc_html__( 'Hilfe für Redakteure', 'wppoland' )
	);
} );

// Keine Sprachliste unter dem Formular.
add_filter( 'login_display_language_dropdown', '__return_false' );

Details, die erst im Quellcode des Kerns sichtbar werden:

  • Der Standardtitel setzt sich aus dem Namen des Bildschirms, dem Namen der Website und dem Wort WordPress am Ende zusammen. Im Wiederherstellungsmodus stellt der Kern ein Präfix voran, bevor er den Filter aufruft. Ein Callback, der den Titel nur aus $title neu baut, verliert dieses Präfix, und der Administrator sieht im Tab nicht mehr, dass die Website im Wiederherstellungsmodus läuft. Ist das wichtig, ändern Sie $login_title, statt ihn zu ersetzen.
  • Die Sprachliste erscheint nur, wenn mindestens ein zusätzliches Sprachpaket installiert ist, und nie im Fenster zur erneuten Anmeldung im Dashboard. Sie auszublenden ändert die Sprache des Kontos nicht: Nach dem Login gilt die Einstellung im Profil.
  • login_site_html_link ersetzt das ganze <a>-Element, das Escaping von URL und Text liegt also bei Ihnen.
  • Der Link zur Datenschutzerklärung unter dem Formular kommt aus the_privacy_policy_link() und erscheint, sobald eine Datenschutzseite festgelegt ist. Blenden Sie ihn auf Websites, die über ein Registrierungsformular Daten erheben, nicht per CSS aus.

#Welche Sicherheits-Header WordPress auf wp-login.php sendet

Bevor Sie eigene Header oder Meta-Tags für die Login-Seite ergänzen, prüfen Sie, was der Kern bereits tut. Laut default-filters.php und wp-login.php:

  • send_frame_options_header() an login_init (seit 3.1.3) sendet X-Frame-Options: SAMEORIGIN, und seit WordPress 6.9 ergänzt dieselbe Funktion Content-Security-Policy: frame-ancestors 'self'. Die Login-Seite lässt sich nicht auf einer fremden Domain in einen Frame einbetten.
  • wp_admin_headers() an login_init (seit 4.9) sendet Referrer-Policy: strict-origin-when-cross-origin; der Filter admin_referrer_policy ändert den Wert.
  • wp_robots_sensitive_page() (seit 5.7) ergänzt noindex und noarchive im Robots-Meta-Tag, das wp_robots an login_head ausgibt.
  • wp_strict_cross_origin_referrer() (seit 5.7) ergänzt ein Referrer-Meta-Tag mit derselben Richtlinie.
  • wp_site_icon an login_head gibt das Favicon aus der Einstellung Website-Icon aus.

In der Praxis verdoppelt ein eigenes Snippet, das ein Robots-Meta-Tag mit noindex oder einen Favicon-Link an login_head ausgibt, nur vorhandene Tags. X-XSS-Protection sollten Sie gar nicht setzen. MDN beschreibt den Header als nicht standardisiert und veraltet, warnt, dass er auf ansonsten sicheren Websites XSS-Lücken erzeugen kann, und empfiehlt Content-Security-Policy. Header für die gesamte Website (HSTS, CSP) gehören in die Server- oder CDN-Konfiguration, nicht in PHP an login_init, damit sie auch wp-admin und REST abdecken.

#Angepasste WordPress-Login-Seite funktioniert nicht

CSS wird nicht angewendet

  • Dateipfad der CSS-Datei überprüfen (Dateiname im Code und im Theme müssen übereinstimmen)
  • Versionsnummer im Enqueue erhöhen oder Browser-Cache leeren
  • Priorität der Hooks überprüfen

Logo wird nicht angezeigt

  • Dateiberechtigungen überprüfen
  • Bei SVG prüfen, ob der Server den MIME-Typ image/svg+xml sendet
  • Pfad mit get_stylesheet_directory_uri() überprüfen

Umleitungsschleifen

Konflikte mit Sicherheits-Plugins

  • Ein Plugin nach dem anderen testen
  • Ladereihenfolge der Hooks überprüfen
  • Plugin-Dokumentation konsultieren

#Login-Branding auf Staging testen

Gehen Sie auf einer Kopie der Produktion der Reihe nach vor:

  1. CSS und Logo hochladen; wp-login.php ohne Cache öffnen (privates Fenster).
  2. Auf das Logo klicken: Sie landen auf dem Frontend des Kunden, nicht auf wordpress.org.
  3. Mit gültigem Konto anmelden, abmelden, mit falschem Passwort anmelden: Die Meldung ist generisch.
  4. Passwort-Wiederherstellung und Reset-Mail auf einer Umgebung mit eingerichtetem SMTP prüfen.
  5. Ist 2FA aktiv, den kompletten Ablauf einmal am Desktop und einmal am Telefon durchspielen.
  6. Vorübergehend auf ein Standard-Theme wechseln: Verschwindet das Branding, obwohl es global gelten sollte, gehört der Code in ein Must-use-Plugin.
  7. Dateipfade und Filterliste in der README des Projekts festhalten, damit der nächste Entwickler nicht in fünf Snippet-Plugins nach der Logik sucht.

Nach der Abnahme denselben Smoke-Test direkt nach dem Deploy auf Produktion wiederholen.

#Zusammenfassung

Eine angepasste Anmeldeseite ist wenig Code mit großer Wirkung auf den Eindruck eines Projekts.

Wichtige Punkte:

  • Branding: Logo, Link auf die Startseite, Linktext über login_headertext
  • Styling: eigene, versionierte style-login.css über login_enqueue_scripts
  • Sicherheit: generische Fehlermeldungen, 2FA für Administratoren, Versuchsbegrenzung auf Server oder WAF
  • Wackeln: shake_error_codes statt des veralteten remove_action
  • Ort: Child-Theme oder Must-use-Plugin, nie Kerndateien

Geben Sie dem Kunden eine einseitige Notiz mit: wo der Code liegt, wie das Logo getauscht wird und welche URL für Mitarbeiter-Logins gilt. Mehr über unsere WordPress-Sicherheitsaudits.

Nächster Schritt

Machen Sie aus dem Artikel eine echte Umsetzung

Dieser Block stärkt die interne Verlinkung und führt Nutzer gezielt zum nächsten sinnvollen Schritt im Service- und Content-System.

Soll das Thema auf Ihrer Website umgesetzt werden?

Ich kann daraus ein konkretes Audit, Hardening-Maßnahmen und einen priorisierten Fix-Plan ableiten.

Relevanter Cluster

Weitere WordPress-Dienste und Wissensbasis entdecken

Stärken Sie Ihr Unternehmen mit professionellem technischen Support in den Kernbereichen des WordPress-Ökosystems.

Wie ändere ich das WordPress-Login-Logo ohne Plugin?#
Hängen Sie eine Funktion an login_enqueue_scripts, geben Sie CSS für #login h1 a mit dem Kundenlogo aus Child-Theme oder Must-use-Plugin aus und leiten Sie den Logo-Link mit login_headerurl auf die Startseite.
Warum entfernt remove_action für wp_shake_js das Wackeln nicht?#
Seit WordPress 5.4 hängt der Kern wp_shake_js an login_footer statt an login_head. Die stabile Methode ist der Filter shake_error_codes mit einem leeren Array.
Wo sollte der Code für die Login-Anpassung liegen?#
Im Child-Theme, wenn das Branding Teil des Kundenprodukts ist, oder in einem Must-use-Plugin, wenn es einen Theme-Wechsel überstehen soll. Nie in Kerndateien.
Stoppen generische Fehlermeldungen Brute-Force-Angriffe?#
Nein. Sie erschweren die Enumeration von Benutzernamen. Rate Limiting auf Server oder WAF, starke Passwörter und 2FA für Administratoren bleiben nötig.
Muss ich meta robots noindex auf wp-login.php ergänzen?#
Nein. Seit WordPress 5.7 setzt der Kern auf der Login-Seite selbst noindex und noarchive, ein eigenes Snippet verdoppelt nur das Tag.

Sie brauchen ein FAQ für Branche und Zielmarkt? Wir erstellen eine Version passend zu Ihren Business-Zielen.

Kontakt aufnehmen

Ähnliche Artikel