web-dev-qa-db-fra.com

Comment protéger les pages avec une double authentification: mot de passe + email (dans un champ personnalisé)

Je souhaite étendre la protection des publications WordPress par un mot de passe en ajoutant un champ de saisie supplémentaire pour le courrier électronique de l'utilisateur.

Donc, pour voir le contenu, l'utilisateur devra connaître le mot de passe et le courrier électronique précédemment transmis qui sont stockés dans le champ méta personnalisé de la publication protégée.

J'essayais de trouver un bon crochet pour vérifier ce champ supplémentaire, mais sans succès. Pourriez-vous me donner quelques idées sur la façon de le faire? Je ne souhaite pas créer de compte utilisateur pour ce type de fonctionnalité.

8
Abed

Lorsque vous définissez une publication comme protégée par mot de passe, la protection est activée sur la fonction get_the_content(). Là, WordPress recherche un cookie post-mot de passe et, s'il n'est pas défini, non valide ou expiré, affichez le formulaire du mot de passe.

Ce formulaire de mot de passe est envoyé à wp-login.php. Dans ce cas, un cookie est défini en fonction du mot de passe indiqué dans le formulaire. La demande est ensuite redirigée vers le message.

Le processus peut être décrit comme suit:

  1. aller à la page de publication
  2. appelle the_content ()
  3. vérifier le cookie
  4. si non valide montrer le mot de passe
  5. soumettre le formulaire à wp_login.php
  6. wp_login.php
  7. définir le cookie basé sur pwd soumis et rediriger vers la page de publication
  8. recommencer la forme # 1

Ce que nous pouvons faire:

  • au point # 4 utilisez le crochet 'the_password_form' pour éditer la sortie du formulaire, en ajoutant un champ pour l’e-mail et un champ masqué avec le post id (à ce stade, nous sommes dans la fonction get_the_content afin que nous ayons accès à la variable globale post)
  • Malheureusement, au point # 3 nous ne pouvons pas modifier le résultat de la vérification des cookies (ou du moins, nous ne pouvons pas le faire de manière simple et fiable). Mais au point # 7 WordPress a un crochet de filtre qui permet de définir l’expiration du cookie: si nous fixons cette heure à un horodatage passé, le cookie ne sera pas défini (et si existx il sera supprimé) et ainsi de suite. la validation échouera. Ainsi, nous pouvons utiliser ce crochet pour vérifier l’email envoyé via le formulaire et, grâce à l’identifiant de la poste dans le champ caché, nous pouvons le comparer aux emails de la méta.

Premier pas:

/**
 * Customize the form, adding a field for email and a hidden field with the post id
 */
add_filter( 'the_password_form', function( $output ) {

  unset( $GLOBALS['the_password_form'] );
  global $post;
  $submit = '<input type="submit" name="Submit" value="' . esc_attr__('Submit') . '" /></p>';
  $hidden = '<input type="hidden" name="email_res_postid" value="' . $post->ID . '">';
  $email = '</p><p><label for="email_res">' . __( 'Email:' );
  $email .= '<input name="email_res" id="email_res" type="text" size="20" /></label></p><p>';
  return str_replace( $submit, $hidden . $email . $submit, $output );

}, 0 );

Et le deuxième:

/**
 * Set the post password cookie expire time based on the email
 */
add_filter( 'post_password_expires', function( $valid ) {

  $postid = filter_input( INPUT_POST, 'email_res_postid', FILTER_SANITIZE_NUMBER_INT );
  $email = filter_input( INPUT_POST, 'email_res', FILTER_SANITIZE_STRING );
  // a timestamp in the past
  $expired = time() - 10 * DAY_IN_SECONDS;
  if ( empty( $postid ) || ! is_numeric( $postid ) ) {
      // empty or bad post id, return past timestamp
      return $expired;
  }
  if ( empty($email) || ! filter_var($email, FILTER_VALIDATE_EMAIL) ) {
      // empty or bad email id, return past timestamp
      return $expired;
  }
  // get the allowed emails
  $allowed = array_filter( (array)get_post_meta( $postid, 'allow_email' ), function( $e ) {
    if ( filter_var( $e, FILTER_VALIDATE_EMAIL) ) return $e;
  });
  if ( ! empty( $allowed ) ) { // some emails are setted, let's check it
    // if the emails posted is good return the original expire time
    // otherwise  return past timestamp
    return in_array( $email, $allowed ) ? $valid : $expired;
  }
  // no emails are setted, return the original expire time
  return $valid;

}, 0 );

Nous avons fini.

Créez maintenant une publication, enregistrez-la en tant que mot de passe protégé et définissez quelques courriels autorisés dans des champs personnalisés à l'aide de la clé'allow_email'. Il n'y a pas de limite au nombre d'emails que vous pouvez ajouter ...


Réglages:

Custom fields to allow email post protection


post protection via password


Résultat (TwentyThirteen sans style supplémentaire):

Result in TwentyThirteen with no additional styling

7
gmazzap