You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WordPress指定加密页1天有效期独立密码无法生效问题

解决WordPress加密页面的临时独立密码验证问题

问题背景

通过WordPress自带页面可见性设置了通用密码加密页面,用Contact Form7搭建请求表单,希望给提交表单的用户自动发送1天有效期的独立临时密码,过期后需重新申请。现有代码能生成带有效期的密码并发送邮件,但生成的密码无法解锁加密页面,试用多款插件也未解决。

原代码如下:

add_action( 'wpcf7_mail_sent', 'custom_generate_password', 10, 1 );

function custom_generate_password( $contact_form ) {

    // Get the ID of the contact form that triggered the action hook

    $form_id = $contact_form->id();

    // Check if the contact form ID matches the one you want to use

    if ( $form_id == 123 ) { // Replace 123 with the ID of your contact form

        // Get the submitted form data

        $submission = WPCF7_Submission::get_instance();

        if ( $submission ) {

            $posted_data = $submission->get_posted_data();

            // Get the user's email address from the form submission

            $user_email = $posted_data['your-email'];

            // Generate a unique password

            $new_password = wp_generate_password( 12, false );

            // Set the expiry time for the password (30 minutes from now)

            $expiry_time = time() + ( 30 * 60 );

            // Save the password and expiry time to the user's session

            session_start();

            $_SESSION['password'] = $new_password;

            $_SESSION['expiry_time'] = $expiry_time;

            // Get the URL of the password-protected page

            $page_url = get_permalink( $page_id );

            // Create the email message

            $to = $user_email;

            $subject = 'Your password for the protected page';

            $message = 'Your password is: ' . $new_password . '\n\n';

            $message .= 'This password will expire at: ' . date( 'Y-m-d H:i:s', $expiry_time ) . '\n\n';

            $message .= 'To access the protected page, please go to: ' . $page_url;

            // Send the email

            wp_mail( $to, $subject, $message );

        }

    }

}

原代码问题分析

  1. 密码存储逻辑无效:WordPress默认的页面加密验证只读取后台设置的通用密码,不会识别存在session中的自定义密码,所以生成的密码无法解锁页面。
  2. 未定义变量:代码中$page_id未赋值,会导致无法获取加密页面的正确链接。

可行解决方案

步骤1:修改表单提交后的临时密码存储逻辑

替换原有的custom_generate_password函数,将临时密码和有效期存储到WordPress选项中,关联用户邮箱和页面ID:

add_action( 'wpcf7_mail_sent', 'custom_generate_temp_password', 10, 1 );
function custom_generate_temp_password( $contact_form ) {
    // 替换为你的Contact Form7表单ID
    $target_form_id = 123;
    // 替换为你的加密页面ID
    $protected_page_id = 456;

    if ( $contact_form->id() != $target_form_id ) return;

    $submission = WPCF7_Submission::get_instance();
    if ( !$submission ) return;

    $posted_data = $submission->get_posted_data();
    $user_email = $posted_data['your-email'] ?? '';
    if ( empty($user_email) ) return;

    // 生成12位临时密码
    $temp_password = wp_generate_password( 12, false );
    // 设置1天有效期(86400秒)
    $expiry_time = time() + 86400;

    // 用邮箱哈希+页面ID作为唯一键存储临时密码
    $option_key = 'temp_page_password_' . $protected_page_id . '_' . md5($user_email);
    update_option( $option_key, [
        'password' => $temp_password,
        'expiry' => $expiry_time
    ], false );

    // 获取加密页面链接
    $page_url = get_permalink( $protected_page_id );
    // 发送通知邮件
    $to = $user_email;
    $subject = '你的加密页面临时访问密码';
    $message = "你的临时密码:{$temp_password}\n\n";
    $message .= "密码有效期至:" . date( 'Y-m-d H:i:s', $expiry_time ) . "\n\n";
    $message .= "访问页面:{$page_url}";

    wp_mail( $to, $subject, $message );
}

步骤2:添加自定义密码验证逻辑

通过过滤器替换WordPress默认的页面加密验证,支持临时密码的校验:

add_filter( 'post_password_required', 'custom_verify_temp_page_password', 20, 2 );
function custom_verify_temp_page_password( $required, $post ) {
    // 替换为你的加密页面ID
    $protected_page_id = 456;
    if ( $post->ID != $protected_page_id ) return $required;

    // 已通过通用密码验证,直接放行
    if ( !$required ) return false;

    // 检查提交的临时密码
    if ( isset($_POST['post_password']) ) {
        $submitted_pass = $_POST['post_password'];
        $temp_pass_prefix = 'temp_page_password_' . $protected_page_id . '_';
        $all_options = wp_load_alloptions();
        
        // 遍历所有临时密码记录,匹配密码并检查有效期
        foreach ( $all_options as $key => $value ) {
            if ( strpos($key, $temp_pass_prefix) === 0 ) {
                $temp_data = maybe_unserialize($value);
                if ( $temp_data['password'] === $submitted_pass && time() < $temp_data['expiry'] ) {
                    // 验证通过,设置WordPress认可的登录Cookie
                    setcookie( 'wp-postpass_' . COOKIEHASH, wp_hash($submitted_pass), time() + 86400, COOKIEPATH, COOKIE_DOMAIN );
                    return false;
                }
            }
        }
    }

    // 临时密码验证失败,保留默认通用密码验证
    return $required;
}

步骤3:添加过期密码清理任务

定期清理过期的临时密码,避免数据库冗余:

add_action( 'daily_scheduled_cleanup', 'cleanup_expired_temp_passwords' );
function cleanup_expired_temp_passwords() {
    $protected_page_id = 456;
    $temp_pass_prefix = 'temp_page_password_' . $protected_page_id . '_';
    $all_options = wp_load_alloptions();

    foreach ( $all_options as $key => $value ) {
        if ( strpos($key, $temp_pass_prefix) === 0 ) {
            $temp_data = maybe_unserialize($value);
            if ( time() > $temp_data['expiry'] ) {
                delete_option($key);
            }
        }
    }
}

// 注册每天执行的清理任务
add_action( 'wp', function() {
    if ( !wp_next_scheduled( 'daily_scheduled_cleanup' ) ) {
        wp_schedule_event( time(), 'daily', 'daily_scheduled_cleanup' );
    }
} );

注意事项

  • 务必将代码中的123(表单ID)和456(加密页面ID)替换为你实际的ID值。
  • 代码需添加到主题的functions.php文件或自定义插件中。
  • 临时密码和通用密码可以同时生效,用户输入任意有效密码均可解锁页面。

内容的提问来源于stack exchange,提问作者Devil mind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 02:21:07