Cómo proteger páginas con doble autenticación: contraseña + correo electrónico (en campo personalizado)

8

Me gustaría extender la protección con contraseña de WordPress de las publicaciones agregando un campo de entrada adicional para el correo electrónico del usuario.

Por lo tanto, para ver el contenido, el usuario tendrá que conocer la contraseña y el correo electrónico proporcionado previamente que se almacena en el metacampo personalizado de la publicación protegida.

Estaba tratando de encontrar un buen gancho comprobando ese campo extra pero sin ningún éxito. ¿Podrías darme algunas ideas para hacerlo? No quiero crear cuentas de usuario para este tipo de función.

Una cama
fuente

Respuestas:

7

Cuando configura una publicación como protegida por contraseña, la protección ocurre en la get_the_content()función. Allí WordPress busca una cookie de contraseña de publicación, y si no se configura, no es válida o caducó, muestre el formulario de contraseña.

Este formulario de contraseña se envía wp-login.php, allí se configura una cookie de acuerdo con la contraseña escrita en el formulario, luego la solicitud se redirige a la publicación nuevamente.

El proceso puede describirse así:

  1. ir a la página de publicación
  2. llame al_contenido ()
  3. revisa la cookie
  4. si no es válido, muestra el formulario de contraseña
  5. enviar formulario a wp_login.php
  6. wp_login.php
  7. configura la cookie en función de la contraseña enviada y redirige a la página de publicación
  8. comenzar de nuevo formulario # 1

Lo que podemos hacer:

  • en el punto # 4 use el gancho 'the_password_form'para editar la salida del formulario, agregando un campo para el correo electrónico y un campo oculto con la identificación de publicación (en este punto estamos dentro de la get_the_contentfunción para tener acceso a la variable de publicación global)
  • Desafortunadamente, en el punto 3 no podemos cambiar el resultado de la verificación de cookies (o al menos no podemos hacerlo de una manera fácil y confiable). Pero en el punto n . ° 7, WordPress tiene un enlace de filtro que permite establecer la caducidad de la cookie: si establecemos ese tiempo en una marca de tiempo pasada, entonces la cookie no se establecerá (y si existx se eliminará) y la validación fallará . Por lo tanto, podemos usar ese gancho para verificar el correo electrónico enviado a través del formulario y, gracias a la identificación de la publicación en el campo oculto, podemos compararlo con los correos electrónicos en el meta, si el correo electrónico no se proporciona o es incorrecto, devolvemos una marca de tiempo anterior.

Primer paso:

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

Y el segundo:

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

Hemos terminado.

Ahora cree una publicación, guárdela como protegida por contraseña y configure algunos correos electrónicos permitidos en campos personalizados con la tecla 'allow_email'. No hay límite en el número de correos electrónicos que puede agregar ...


Configuraciones:

Campos personalizados para permitir la protección de correo electrónico


protección posterior a través de contraseña


Resultado (TwentyThirteen sin estilo adicional):

Resultado en TwentyThirteen sin estilo adicional

gmazzap
fuente