it-swarm.com.de

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

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

Damit der Inhalt angezeigt werden kann, muss der Benutzer das Kennwort 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 das 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.

8
Abed

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

Dieses Passwort-Formular wird an wp-login.php gesendet. Dort wird ein Cookie gemäß dem im Formular eingegebenen Passwort abgelegt. Anschließend wird die Anfrage erneut an den Post weitergeleitet.

Der Prozess kann wie folgt beschrieben werden:

  1. gehe zur Beitragsseite
  2. rufe the_content () auf
  3. überprüfen Sie den Cookie
  4. wenn nicht gültig, zeigen Sie das Passwort-Formular
  5. senden Sie das Formular an wp_login.php
  6. wp_login.php
  7. setzen Sie den Cookie basierend auf der übermittelten pwd und leiten Sie zum Posten der Seite weiter
  8. starten Sie erneut von # 1

Was wir tun können:

  • an Punkt # 4 benutze den Haken 'the_password_form', um die Ausgabe des Formulars zu bearbeiten, füge ein Feld für die E-Mail und ein verstecktes Feld mit der Beitrags-ID hinzu (an diesem Punkt befinden wir uns innerhalb der Funktion get_the_content, also haben wir Zugriff auf globale Postvariable)
  • Leider können wir an Punkt # 3 das Ergebnis der Cookie-Überprüfung nicht ändern (oder zumindest nicht auf einfache und zuverlässige Weise). Aber bei Punkt # 7 WordPress gibt es einen Filter-Haken, der es erlaubt, den Cookie-Ablauf zu setzen: Wenn wir diese Zeit auf einen vergangenen Zeitstempel setzen, wird der Cookie nicht gesetzt (und falls vorhanden, wird er gelöscht) und so weiter Die Validierung schlägt fehl. Wir können diesen Haken verwenden, um die über das Formular übermittelte E-Mail zu überprüfen. Dank der Post-ID im ausgeblendeten Feld können wir sie mit den E-Mails in der 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 einige zulässige E-Mails in benutzerdefinierten Feldern mit dem Schlüssel'allow_email'fest. Die Anzahl der E-Mails, die Sie hinzufügen können, ist unbegrenzt ...


Die Einstellungen:

Custom fields to allow email post protection


post protection via password


Ergebnis (TwentyThirteen ohne zusätzliches Styling):

Result in TwentyThirteen with no additional styling

7
gmazzap