Come posso reindirizzare l'utente dopo l'inserimento di una password errata?
Sto utilizzando wp_login_form()
per visualizzare il modulo di accesso in una finestra di dialogo jQuery.
Se l'utente inserisce una password errata, viene reindirizzato al backend. Non voglio questo comportamento. C'è un modo per notificare all'utente che ha inserito una password errata e mantenerlo sulla stessa pagina?
Prima che esistesse wp_login_form()
utilizzavo un plugin. Spero di poter evitare l'uso di un plugin per questa funzionalità.
Il mio codice:
wp_login_form( array(
'label_remember' => __( 'Ricordami' ),
'label_log_in' => __( 'Accedi' )
) );

Sono arrivato qui da Google. Ma la risposta non mi ha soddisfatto. Ho cercato per un po' e ho trovato una soluzione migliore.
Aggiungi questo al tuo file functions.php:
add_action( 'wp_login_failed', 'my_front_end_login_fail' ); // hook per il login fallito
function my_front_end_login_fail( $username ) {
$referrer = $_SERVER['HTTP_REFERER']; // da dove proviene il tentativo di login?
// se c'è un referrer valido e non è la schermata di login predefinita
if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') ) {
wp_redirect( $referrer . '?login=failed' ); // aggiungiamo qualche informazione (login=failed) all'URL per il tema
exit;
}
}

Grazie Alexey, proverò questa soluzione (dato che sto ancora usando un plugin)

La soluzione di Alexey funziona quando vengono inserite credenziali errate, ma purtroppo fallisce quando l'utente dimentica di inserire username o password. Apparentemente Wordpress in questo caso non tenta nemmeno di effettuare il login, quindi l'azione wp_login_failed non viene eseguita.

Userei wp_get_referer() qui per risparmiare tempo: http://codex.wordpress.org/Function_Reference/wp_get_referer

Il metodo attuale che sto utilizzando per gestire tutti i problemi delineati qui funziona alla grande anche con username/password vuoti e non si basa su javascript (anche se il js potrebbe essere utile insieme a questo).
add_action( 'wp_login_failed', 'custom_login_failed' );
function custom_login_failed( $username )
{
$referrer = wp_get_referer();
if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer,'wp-admin') )
{
wp_redirect( add_query_arg('login', 'failed', $referrer) );
exit;
}
}
La chiave è questo filtro per modificare il trattamento di username/password vuoti:
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3);
function custom_authenticate_username_password( $user, $username, $password )
{
if ( is_a($user, 'WP_User') ) { return $user; }
if ( empty($username) || empty($password) )
{
$error = new WP_Error();
$user = new WP_Error('authentication_failed', __('<strong>ERRORE</strong>: Username non valido o password errata.'));
return $error;
}
}
Puoi spingerti oltre e sostituire completamente wp-login.php reindirizzando gli utenti alla tua pagina di login personalizzata e utilizzare quella pagina anche per il reindirizzamento in caso di login fallito. Codice completo:
/**
* Azioni per la Pagina di Login Personalizzata
*/
// Modifica l'URL di login in tutto il sito per puntare alla pagina di login personalizzata
add_filter( 'login_url', 'custom_login_url', 10, 2 );
// Reindirizza wp-login alla pagina di login personalizzata con query var di errore quando necessario
add_action( 'login_head', 'custom_redirect_login', 10, 2 );
// Aggiorna il login fallito per riportare l'utente al form personalizzato con una query var
add_action( 'wp_login_failed', 'custom_login_failed', 10, 2 );
// Aggiorna l'autenticazione per restituire un errore quando uno o entrambi i campi sono vuoti
add_filter( 'authenticate', 'custom_authenticate_username_password', 30, 3);
// Aggiunge automaticamente il form di login alla pagina "login"
add_filter( 'the_content', 'custom_login_form_to_login_page' );
/**
* Funzioni per la Pagina di Login Personalizzata
*/
function custom_login_url( $login_url='', $redirect='' )
{
$page = get_page_by_path('login');
if ( $page )
{
$login_url = get_permalink($page->ID);
if (! empty($redirect) )
$login_url = add_query_arg('redirect_to', urlencode($redirect), $login_url);
}
return $login_url;
}
function custom_redirect_login( $redirect_to='', $request='' )
{
if ( 'wp-login.php' == $GLOBALS['pagenow'] )
{
$redirect_url = custom_login_url();
if (! empty($_GET['action']) )
{
if ( 'lostpassword' == $_GET['action'] )
{
return;
}
elseif ( 'register' == $_GET['action'] )
{
$register_page = get_page_by_path('register');
$redirect_url = get_permalink($register_page->ID);
}
}
elseif (! empty($_GET['loggedout']) )
{
$redirect_url = add_query_arg('action', 'loggedout', custom_login_url());
}
wp_redirect( $redirect_url );
exit;
}
}
function custom_login_failed( $username )
{
$referrer = wp_get_referer();
if ( $referrer && ! strstr($referrer, 'wp-login') && ! strstr($referrer, 'wp-admin') )
{
if ( empty($_GET['loggedout']) )
wp_redirect( add_query_arg('action', 'failed', custom_login_url()) );
else
wp_redirect( add_query_arg('action', 'loggedout', custom_login_url()) );
exit;
}
}
function custom_authenticate_username_password( $user, $username, $password )
{
if ( is_a($user, 'WP_User') ) { return $user; }
if ( empty($username) || empty($password) )
{
$error = new WP_Error();
$user = new WP_Error('authentication_failed', __('<strong>ERRORE</strong>: Username non valido o password errata.'));
return $error;
}
}
function custom_login_form_to_login_page( $content )
{
if ( is_page('login') && in_the_loop() )
{
$output = $message = "";
if (! empty($_GET['action']) )
{
if ( 'failed' == $_GET['action'] )
$message = "C'è stato un problema con il tuo username o password.";
elseif ( 'loggedout' == $_GET['action'] )
$message = "Sei stato disconnesso.";
elseif ( 'recovered' == $_GET['action'] )
$message = "Controlla la tua email per il link di conferma.";
}
if ( $message ) $output .= '<div class="message"><p>'. $message .'</p></div>';
$output .= wp_login_form('echo=0&redirect='. site_url());
$output .= '<a href="'. wp_lostpassword_url( add_query_arg('action', 'recovered', get_permalink()) ) .'" title="Recupera Password">Password dimenticata?</a>';
$content .= $output;
}
return $content;
}
Personalizza e aggiungi questi per inserire il tuo logo nella pagina wp-login per il recupero password:
// chiamato solo nella pagina di login
add_action( 'login_enqueue_scripts', 'custom_login_css', 10 );
function custom_login_css() { wp_enqueue_style( 'custom_login_css', get_template_directory_uri() .'/library/css/login.css', false ); }
// modifica il link del logo da wordpress.org al tuo sito
add_filter( 'login_headerurl', 'custom_login_logo_url' );
function custom_login_logo_url() { return home_url(); }
// modifica il testo alternativo del logo per mostrare il nome del tuo sito
add_filter( 'login_headertitle', 'custom_login_title' );
function custom_login_title() { return get_option('blogname'); }
CSS per il logo di login:
.login h1 a {
background: url(../images/login-logo.png) no-repeat top center;
width: 274px;
height: 63px;
text-indent: -9999px;
overflow: hidden;
padding-bottom: 15px;
display: block;
}
MODIFICA: Ho appena implementato questo su un altro sito da zero, e ho trovato il metodo "step further" sopra più completo, e ho corretto piccoli errori di sintassi negli "add_actions". Aggiunti alcuni commenti e un metodo per aggiungere automaticamente il form di login alla pagina di login senza un file template separato. Il metodo del form di login dovrebbe funzionare nella maggior parte dei casi, poiché è collegato a "the_content", potrebbe causare un problema se hai più di un loop nella pagina di login, in quel caso usa semplicemente un template page-login.php.

Grazie, darò un'occhiata a questo (e vedrò se riesco a farlo funzionare in combinazione con login di terze parti come Twitter e FB)

Jake - questa è una soluzione completa e ben fatta. Grazie per averla condivisa. +1

Questo è sostanzialmente racchiuso in un plugin chiamato Sewn In Template Login, un plugin piuttosto completo e leggero. https://wordpress.org/plugins/sewn-in-template-log-in/

wp_login_form()
crea un modulo con un attributo action di site_url/wp-login.php
, il che significa che quando clicchi sul pulsante di invio il modulo viene inviato a site_url/wp-login.php
che ignora redirect_to in caso di errori (come password errata). Quindi nel tuo caso puoi scegliere tra continuare a usare un plugin o ricreare l'intero processo di login, in modo da avere il controllo sugli errori. Dai un'occhiata a Verifica del nome utente corretto su un modulo di login personalizzato che è una domanda molto simile.

Una soluzione per il punto sollevato da Szczepan Hołyszewski riguardo ai campi vuoti nella soluzione accettata, il seguente jQuery impedirà di andare alla pagina standard wp-login: (da aggiungere al template della pagina di login o a footer.php)
jQuery("#loginform-custom").submit(function(){
var isFormValid = true;
jQuery("input").each(function()
{
if (jQuery.trim($(this).val()).length == 0){
jQuery(this).addClass("submit_error");
isFormValid = false;
}
else {
jQuery(this).removeClass("submit_error");
}
});
return isFormValid;
});

Il seguente codice ha funzionato per me. Entrambi questi hook possono essere trovati all'interno della funzione wp_authenticate
in wp-includes/puggabel.php
.
- Controlla tramite il filtro
authenticate
se il modulo di login è privo di username o password.
function wpse_15633_redirectMissingDataLoginForm($user, $username, $password)
{
$errors = [];
empty(trim($password)) && $errors[] = 'password_empty';
empty(trim($username)) && $errors[] = 'username_empty';
if (! empty($errors)) {
$redirect_url = add_query_arg([
'errors' => join(',', $errors),
], site_url('login', 'login_post'));
if (wp_safe_redirect($redirect_url)) {
exit;
}
}
return $user;
}
add_filter('authenticate', 'wpse_15633_redirectMissingDataLoginForm', 10, 3);
- Controlla tramite l'azione
wp_login_failed
se l'autenticazione dello username e della password forniti è fallita.
function wpse_15633_redirectFailedLoginForm($username, $error)
{
$redirect_url = add_query_arg([
'errors' => $error->get_error_code(),
], site_url('login', 'login_post'));
if (wp_safe_redirect($redirect_url)) {
exit;
}
}
add_action('wp_login_failed', 'wpse_15633_redirectFailedLoginForm', 10, 2);

Un'aggiunta alla risposta di Alexey. Puoi aggiungere una funzione jQuery per verificare che uno dei campi non sia vuoto. In questo modo il modulo non verrà inviato a meno che non ci sia qualcosa da controllare, evitando che WordPress reindirizzi a /wp-login.php.
<script>
$("#wp-submit").click(function() {
var user = $("input#user_login").val();
if (user == "") {
$("input#user_login").focus();
return false;
}
});
</script>
Ancora non sono sicuro su come sistemare l'aspetto del recupero password

Si prega di notare che WordPress carica jQuery in modalità "No Conflict". L'alias $
non funziona.

Aggiungendo alla risposta utile di @alexey e includendo qualcosa per gestire il problema menzionato da altri.
Il suo codice da inserire nel file functions.php:
add_action( 'wp_login_failed', 'my_front_end_login_fail' ); // hook per il login fallito
function my_front_end_login_fail( $username ) {
$referrer = $_SERVER['HTTP_REFERER']; // da dove proviene l'invio del form?
// se c'è un referrer valido e non è la schermata di login predefinita
if ( !empty($referrer) && !strstr($referrer,'wp-login') && !strstr($referrer,'wp-admin') ) {
wp_redirect( $referrer . '?login=failed' ); // aggiungiamo alcune informazioni (login=failed) all'URL per il tema da utilizzare
exit;
}
}
Tuttavia, come hanno notato altri, se i campi sono vuoti, WordPress non si preoccupa di convalidare e gli utenti finiscono comunque nella schermata di login del backend.
Per ovviare a questo, aggiungo uno script subito dopo la creazione del form che aggiunge l'attributo required
agli input in modo che il browser blocchi qualsiasi invio se i campi sono vuoti.
Sulla pagina dove si trova il tuo form:
<?php
$args = array(
'form_id' => 'YOUR-FORM-NAME',
);
wp_login_form( $args );
?>
<script>
if(jQuery('form#YOUR-FORM-NAME').length) {
jQuery('form#YOUR-FORM-NAME input').each(function() {
jQuery(this).attr("required", true);
});
}
</script>

jQuery("#loginform-custom").submit(function(){
var isFormValid = true;
jQuery("input").each(function()
{
if (jQuery.trim($(this).val()).length == 0){
jQuery(this).addClass("submit_error");
isFormValid = false;
}
else {
jQuery(this).removeClass("submit_error");
}
});
return isFormValid;
});
