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 ); } } }
原代码问题分析
- 密码存储逻辑无效:WordPress默认的页面加密验证只读取后台设置的通用密码,不会识别存在session中的自定义密码,所以生成的密码无法解锁页面。
- 未定义变量:代码中
$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
相关产品推荐
相关产品推荐

