So schützen Sie Seiten mit doppelter Authentifizierung: Passwort + E-Mail (im benutzerdefinierten Feld)

8

Ich möchte den WordPress-Passwortschutz für Beiträge erweitern, indem ich ein zusätzliches Eingabefeld für Benutzer-E-Mails hinzufüge.

Um den Inhalt zu sehen, muss der Benutzer das Passwort und die zuvor angegebene E-Mail-Adresse kennen, die im benutzerdefinierten Metafeld des geschützten Beitrags gespeichert ist.

Ich habe versucht, einen guten Haken zu finden, der dieses zusätzliche Feld überprüft, aber ohne Erfolg. Könnten Sie mir einige Ideen geben, wie man es macht? Ich möchte keine Benutzerkonten für diese Art von Funktion erstellen.

Ein Bett
quelle

Antworten:

7

Wenn Sie einen Beitrag als passwortgeschützt festlegen, erfolgt der Schutz für die get_the_content()Funktion. Dort prüft WordPress auf ein Post-Passwort-Cookie und zeigt das Passwort-Formular an, wenn es nicht gesetzt, ungültig oder abgelaufen ist.

Dieses Passwortformular wird an gesendet wp-login.php, dort wird ein Cookie gemäß dem im Formular angegebenen Passwort gesetzt und die Anfrage erneut an den Beitrag weitergeleitet.

Der Prozess kann folgendermaßen beschrieben werden:

  1. Gehe zur Post-Seite
  2. rufe the_content () auf
  3. Überprüfen Sie den Cookie
  4. Wenn nicht gültig, zeigen Sie das Passwortformular an
  5. Senden Sie das Formular an wp_login.php
  6. wp_login.php
  7. Setzen Sie das Cookie basierend auf dem eingereichten pwd und leiten Sie es zur Post-Seite weiter
  8. Starten Sie erneut von Formular 1

Was wir tun können:

  • Verwenden Sie an Punkt 4 den Hook 'the_password_form', um die Ausgabe des Formulars zu bearbeiten, und fügen Sie ein Feld für die E-Mail und ein verstecktes Feld mit der Post-ID hinzu (an diesem Punkt befinden wir uns innerhalb der get_the_contentFunktion, sodass wir Zugriff auf die globale Post-Variable haben).
  • Leider können wir bei Punkt 3 das Ergebnis der Cookie-Prüfung nicht ändern (oder zumindest nicht auf einfache und zuverlässige Weise). Aber an Punkt 7 hat WordPress einen Filter-Hook, mit dem der Cookie-Ablauf festgelegt werden kann: Wenn wir diese Zeit auf einen vergangenen Zeitstempel setzen, wird das Cookie nicht gesetzt (und wenn es existiert, wird es gelöscht) und die Validierung schlägt fehl . Mit diesem Hook können wir die über das Formular gesendete E-Mail überprüfen und dank der Post-ID im ausgeblendeten Feld mit den E-Mails im Meta vergleichen. Wenn die E-Mail nicht angegeben oder falsch ist, geben wir einen vergangenen Zeitstempel zurück.

Erster Schritt:

/**
 * 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 );

Und der zweite:

/**
 * 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 );

Wir sind fertig.

Erstellen Sie nun einen Beitrag, speichern Sie ihn als kennwortgeschützt und legen Sie mit dem Schlüssel einige zulässige E-Mails in benutzerdefinierten Feldern fest 'allow_email'. Die Anzahl der E-Mails, die Sie hinzufügen können, ist unbegrenzt.


Die Einstellungen:

Benutzerdefinierte Felder, um den Schutz von E-Mail-Posts zu ermöglichen


Postschutz per Passwort


Ergebnis (TwentyThirteen ohne zusätzliches Styling):

Ergebnis in TwentyThirteen ohne zusätzliches Styling

gmazzap
quelle