web-dev-qa-db-fra.com

Formulaire de connexion personnalisé redirigé vers un site externe

J'ai créé une page privée, mais cette page doit être plus que disponible en entrant un code pour une page classée privée dans les paramètres de publication de Visibility. J'ai donc créé une page et ajouté une instruction if/else à vérifier. si l'utilisateur est connecté ou non. Si tel est le cas, le contenu s'affiche comme il se doit, s'il ne l'est pas, le formulaire de connexion apparaît et l'utilisateur est invité à se connecter, ce qui apparaît comme il se doit.

Le problème est que, après s'être connectés en utilisant le formulaire, ils sont redirigés vers la page d'administration. J'ai ajouté une redirection vers la page de connexion pour accéder à la page que je veux, mais cela ne semble pas fonctionner. Est-ce que je fais la redirection de manière incorrecte?

<?php
/*
Template Name: Minutes
*/
?>

<?php get_header(); ?>

<?php get_template_part( 'templates/content', 'nav' ); ?>  
<?php get_template_part( 'templates/content', 'breadcrumb' ); ?> 




<section class="band bottom u-full-width" style="margin-top: 2%">
    <div class="container">
        <div class="row">


<?php if (is_user_logged_in()) { ?>


<div class="ten columns" >

<h5><b>Click the Plus (+) Sign to expend the list of available minutes per section</b></h5>   

Plus more code


<?php } else {
    echo 'We are sorry, but this area is only for registered, logged in users. If you are a registered user, please use the link below to login to the site to view content not available to the general public.  If you have any questions, please contact us.';
    wp_login_form(array('redirect' => 'http://etomv2.bambergmarketing.com/meeting-minutes'));
}
?>

</div>

</div></div>
</section>

<?php get_footer(); ?>
3
Justin Bamberg

Les événements internes expliqués

Quand vous regardez wp_login_form() , vous verrez alors que l'argument redirect demandera une URL absolue. Utilisez donc admin_url() ou site_url() si vous souhaitez lier en interne.

La action/target de ce formulaire n'est pas censée être modifiée (sauf si vous définissez echo sur FALSE et utilisez un remplacement \DOMDocument ou une Regex pour le changer dans la chaîne de sortie):

action="' . esc_url( site_url( 'wp-login.php', 'login_post' ) ) . '" method="post"

Lorsque vous regardez ensuite wp_login.php ET LE case : 'login' | default , vous remarquerez deux choses:

  1. Il y a un filtre pour ajuster la redirection, ce qui peut remplacer tout ce qui est défini dans vos arguments. N'oubliez pas que cela peut même basculer en fonction de l'utilisateur qui effectue l'action de connexion (généralement utilisé pour rediriger des utilisateurs de différents rôles vers différents écrans d'accueil):

    apply_filters( 'login_redirect', $redirect_to, $requested_redirect_to, $user );
    
  2. Ensuite, l'utilisateur est vérifié s'il est authentifié et non pas un objet erroné. En fonction de cela, si la demande n'est pas dirigée vers le côté /wp-admin, la fonction suivante est appelée:

    exit( wp_safe_redirect( $target ) );
    

… Et en utilisant wp_safe_redirect() signifie que vous pouvez pas lien extérieur (figuré à partir de @TheDeadMedic commentaire - merci!).

Solutions

Comme d'habitude dans WordPress, vous avez des options:

  1. Cette fonction se trouve dans pluggable.php , ce qui signifie que vous pouvez la remplacer par votre fonction own . Ce n'est pas très stable (tous les autres plugins peuvent faire la même chose), mais ça ira si vous l'utilisez sur votre site personnel, documentez-le en place et corrigez les problèmes en cas de conflit. Plus d'informations dans cette question et la réponse de @ChipBennet à ce sujet.
  2. Le meilleure solution est de regarder wp_validate_redirect() qui est utilisé en interne par wp_safe_redirect() et de tirer parti du filtre que WP offre à étendre la liste des hôtes autorisés .

    // End of `wp_validate_redirect()`
    $allowed_hosts = (array) apply_filters( 
        'allowed_redirect_hosts', 
        array( $wpp['Host'] ), 
        isset( $lp['Host'] ) ? $lp['Host'] : '' 
    );
    
    if ( 
        isset($lp['Host']) 
        && ( !in_array($lp['Host'], $allowed_hosts) 
        && $lp['Host'] != strtolower($wpp['Host'])) 
    )
        $location = $default;
    

    Dans votre cas, un (mu-) plugin permettant cette redirection ressemblerait à ceci:

    <?php /* Plugin Name: Allow external login redirect */
    add_filter( 'allowed_redirect_hosts', function( Array $hosts, $check )
    {
        return $hosts + [ 'http://etomv2.bambergmarketing.com' ];
    }, 10, 2 );
    

    Jetez également un coup d'œil au deuxième argument de wp_safe_redirect( $target, $fallback ) qui est utilisé pour wp_validate_redirect(). Il est défini comme filtre. Cela signifie que vous pouvez rediriger vers une autre URL externe en cas d'échec de votre connexion. Ou vous pouvez rediriger localement vers une page d'erreur (ou simplement la page actuelle, qui est la valeur par défaut):

    apply_filters( 'wp_safe_redirect_fallback', admin_url(), $status )
    

La deuxième solution est ce que je voudrais utiliser. Vous pouvez également vouloir l'utiliser si vous utilisez un fournisseur externe OAuth contre lequel vous devez valider les utilisateurs.

Remarque

Si vous lisez la documentation et vous posez des questions sur login_post en tant que "schéma", la fonction site_url() est un wrapper pour get_site_url() qui utilise set_url_scheme() en interne. login_post, login et rpc sont égaux à admin, ce qui ajuste l'action correctement:

$scheme = is_ssl() || force_ssl_admin() ? 'https' : 'http';
1
kaiser