Como proteger páginas com autenticação dupla: senha + email (no campo personalizado)

8

Gostaria de estender a proteção de senha das postagens do WordPress adicionando um campo de entrada extra para o email do usuário.

Portanto, para ver o conteúdo, o usuário terá que saber a senha e o e-mail previamente fornecido que está armazenado no meta campo personalizado da postagem protegida.

Eu estava tentando encontrar um bom gancho para checar aquele campo extra, mas sem sucesso algum. Você poderia me dar algumas idéias de como fazer isso? Não quero criar contas de usuário para esse tipo de recurso.

    
por Abed 15.03.2014 / 18:46

1 resposta

7

Quando você define uma postagem como protegida por senha, a proteção acontece na função get_the_content() . Há WordPress verificar um cookie pós-senha, e se não for definido, não válido ou expirado, em seguida, mostre o formulário de senha.

Este formulário de senha é enviado para wp-login.php , onde um cookie é configurado de acordo com a senha escrita no formulário e, em seguida, o pedido é redirecionado para a postagem novamente.

O processo pode ser descrito da seguinte forma:

  1. ir para postar página
  2. ligue para the_content ()
  3. verifique o cookie
  4. se não for válido, mostre o formulário de senha
  5. enviar formulário para wp_login.php
  6. wp_login.php
  7. defina o cookie com base no pwd enviado e redirecione para a página de postagem
  8. inicie novamente o formulário # 1

O que podemos fazer:

  • no ponto # 4 use o gancho 'the_password_form' para editar a saída do formulário, adicionando um campo para o email e um campo oculto com o ID do post ( Neste ponto, estamos dentro da função get_the_content , então temos acesso à variável global post
  • Infelizmente, no ponto # 3 , não podemos alterar o resultado da verificação de cookie (ou pelo menos não podemos de maneira fácil e confiável). Mas no ponto # 7 o WordPress tem um gancho de filtro que permite definir a expiração do cookie: se definirmos esse tempo como um registro de data e hora anterior, o cookie não será definido (e se existx ele será excluído ) e assim a validação falhará. Então podemos usar esse hook para checar o email enviado via formulário e graças ao post id no campo oculto podemos compará-lo com os emails no meta, se o email não for dado ou estiver errado retornamos um timestamp passado.

Primeiro passo:

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

E o 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 );

Nós terminamos.

Agora crie uma postagem, salve como protegido por senha e defina alguns e-mails permitidos em campos personalizados usando a chave 'allow_email' . Não há limite no número de e-mails que você pode adicionar ...

Configurações:

Resultado (TwentyTirteen sem estilo adicional):

    
por gmazzap 16.03.2014 / 06:43