如何使用双重身份验证保护页面:密码+电子邮件(在自定义字段中)

时间:2014-03-15 作者:Abed

我想通过为用户电子邮件添加额外的输入字段来扩展WordPress对帖子的密码保护。

因此,为了查看内容,用户必须知道密码和之前给定的电子邮件,这些电子邮件存储在受保护帖子的自定义元字段中。

我试图找到一个好的钩子来检查那个额外的领域,但没有任何成功。你能告诉我怎么做吗?我不想为这种功能创建用户帐户。

1 个回复
SO网友:gmazzap

当您将帖子设置为受密码保护时,保护发生在get_the_content() 作用WordPress检查post密码cookie,如果未设置、无效或过期,则显示密码表单。

此密码表单提交至wp-login.php, 根据表单中写入的密码设置cookie,然后再次将请求重定向到帖子。

该过程可以这样描述:

转到post页调用内容(),检查cookie,如果无效,则显示密码表单,将表单提交给wp\\U登录。php wp\\u登录。php根据提交的pwd设置cookie,并重定向到post页,重新开始表单1,我们可以做什么:

在点处#4 使用挂钩\'the_password_form\' 要编辑表单的输出,请添加a field for the email and a hidden field with the post id (此时我们在里面get_the_content 函数,这样我们就可以访问全局post变量#3 在那里,我们不能更改cookie检查的结果(或者至少我们不能以一种简单可靠的方式)。但在这一点上#7 WordPress有一个过滤器挂钩,允许设置cookie过期时间:如果我们将该时间设置为过去的时间戳,则不会设置cookie(如果existx,则会将其删除),因此验证将失败。因此,我们可以使用该钩子检查通过表单提交的电子邮件,并且由于隐藏字段中的post id,我们可以将其与meta中的电子邮件进行比较,如果电子邮件没有给出或错误,我们将返回过去的时间戳

/**
 * 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 );
第二点:

/**
 * 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 );
我们完成了。

现在创建帖子,另存为受密码保护的邮件,并使用密钥在自定义字段中设置一些允许的电子邮件\'allow_email\'. 您可以添加的电子邮件数量并没有限制。。。

设置:Custom fields to allow email post protection

<小时>post protection via password

结果(二十三,无其他样式):Result in TwentyThirteen with no additional styling

结束