文章參考自:http://www.tutorialstag.com/WordPress-custom-password-reset-page-template.html#codesyntax_2
密碼重置是一個比稍微複雜的過程,因為這個過程需要更多的數據。
在這篇文章之前,我們先了解一下密碼重置的流程:
首先用户需要重置密碼
- 一、先訪問本頁面,輸入需要重置密碼賬户的 Email 或者用户名。
- 二、系統通過用户輸入的用户名郵箱給用户發送一封郵件,郵件內容中有一個鏈接地址 (還是本頁面),但是這個鏈接地址中包含有一個密匙,所以如果訪問本頁面的地址中沒有密匙,則用户需要輸入用户名或密碼,如果有密匙,那用户是來重置密碼的而不是提交重置密碼的請求。
- 三、用户通過郵件中的地址訪問本頁面 (地址中含有密匙),判斷地址中含有密匙,則用户是來重置密碼的,所以判斷密匙的正確性,如果正確,則通過郵件將生成的新密碼發送給用户,如果不正確,則顯示錯誤信息。
請記住上面説到的兩個 「動作」,重置密碼、提交重置密碼的請求。上面有提到一個密匙,密匙是存儲在數據庫中的,user 表中的 user_activation_key,一般是隨機生成的。
本篇教程呢,以文章模板為例 (使用 url 重寫,請讀者參考前面的文章自行修改),還有由於作者是在自己的電腦上測試,所以並不能百分百確定代碼可用。

第一步:創建模板文件
首先在 twenty ten 主題中創建模板文件:page-passreset.php.
第二步:給模板文件命名
在文件開頭添加代碼
- <?php
- /*
- Template Name: 找回密碼模板
- */
- ?>
第三步:判斷用户是否已經登陸
- <?php
- global $wpdb, $user_ID;
- wp_enqueue_script( 'jquery' ); //加載 jquery,如果你的主題頭部已經引入,請刪掉
- if (!$user_ID) { //判斷用户是否已經登陸
- //接下來的代碼應該添加在這裏
- } else {
- wp_redirect( home_url() ); exit;
- //重定向到首頁
- }
- ?>
第四步:找回密碼錶單
- get_header(); ?>
- <script src="http://code.jquery.com/jquery-1.4.4.js"></script><!--載入 js-->
- <div id="content" role="main">
- <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
- <form class="user_form" id="wp_pass_reset" action="" method="post">
- <input type="text" class="text" name="user_input" value="" /><br />
- <input type="hidden" name="action" value="tg_pwd_reset" />
- <input type="hidden" name="tg_pwd_nonce" value="<?php echo wp_create_nonce("tg_pwd_nonce"); ?>" />
- <!--wp_create_nonce 函數創建隨機數,用於安全驗證-->
- <input type="submit" id="submitbtn" class="reset_password" name="submit" value="Reset Password" />
- </form>
- <div id="result"></div> <!-- To hold validation results -->
- <script type="text/javascript">
- $("#wp_pass_reset").submit(function() {
- $('#result').html('<span class="loading">Validating...</span>').fadeIn();
- var input_data = $('#wp_pass_reset').serialize();
- $.ajax({
- type: "POST",
- url: "<?php echo get_permalink( $post->ID ); ?>",
- data: input_data,
- success: function(msg){
- $('.loading').remove();
- $('<div>').html(msg).appendTo('div#result').hide().fadeIn('slow');
- }
- });
- return false;
- });
- </script>
- <?php endwhile; else : ?>
- <h2><?php _e('沒有找到'); ?></h1>
- <?php endif; ?>
- </div><!-- content -->
- <?php get_footer();
第五步:「重置」 頁面鏈接
這裏説的重置,是在需要輸出當前頁面鏈接地址 (比如重置密碼的郵件中),需要根據當前頁面的 url 形式重置出一個可用的 url 來。你可以將下面的函數添加在頁面頂部 global 變量的後面,也可以放在引入 js 的後面
- function tg_validate_url() {
- global $post;
- $page_url = esc_url(get_permalink( $post->ID )); //獲取本頁面的鏈接地址
- $urlget = strpos($page_url, "?");
- if ($urlget === false) {
- $concate = "?";
- } else {
- $concate = "&";
- }
- return $page_url.$concate; //返回一個類似 example.com/? example.com/?p=123& 這樣的 url
- }
第六步:請求重置密碼
文章最開始説到,本篇教程中需要區分兩個 「動作」,一個是請求重置代碼 (輸入郵箱或用户名),其次是重置密碼 (用户通過郵箱中的鏈接地址來的),下面的代碼需要判斷用户是否提交了數據,所以請注意代碼中最後面的提示,將第四步中的代碼包含在那一對大括號中。
- if($_POST['action'] == "tg_pwd_reset"){ //判斷是否為請求重置密碼
- if ( !wp_verify_nonce( $_POST['tg_pwd_nonce'], "tg_pwd_nonce")) { //檢查隨機數
- exit("不要開玩笑");
- }
- if(empty($_POST['user_input'])) {
- echo "<div > 請輸入用户名或 E-mail 地址</div>";
- exit();
- }
- //過濾提交的數據
- $user_input = $wpdb->escape(trim($_POST['user_input']));
- if ( strpos($user_input, '@') ) { //判斷用户提交的是郵件還是用户名
- $user_data = get_user_by_email($user_input); //通過 Email 獲取用户數據
- if(emptyempty($user_data) || $user_data->caps[administrator] == 1) { //排除管理員
- echo "<div > 無效的 E-mail 地址!</div>";
- exit();
- }
- } else {
- $user_data = get_userdatabylogin($user_input); //通過用户名獲取用户數據
- if(empty($user_data) || $user_data->caps[administrator] == 1) { //排除管理員
- echo "<div > 無效的用户名!</div>";
- exit();
- }
- }
- $user_login = $user_data->user_login;
- $user_email = $user_data->user_email;
- $key = $wpdb->get_var($wpdb->prepare("SELECT user_activation_key FROM $wpdb->users WHERE user_login = %s", $user_login)); //從數據庫中獲取密匙
- if(empty($key)) { //如果為空
- //generate reset keys 生成 keys
- $key = wp_generate_password(20, false); //生成一個 20 位隨機密碼用做密匙
- $wpdb->update($wpdb->users, array('user_activation_key' => $key), array('user_login' => $user_login)); //更新到數據庫
- }
- //郵件內容
- $message = __('有人提交了重置下面賬户密碼的請求:') . "
"
; - $message .= get_option('siteurl') . "
"
; - $message .= sprintf(__('用户名: %s'), $user_login) . "
"
; - $message .= __('如果不是您本人操作,請忽略這個郵件即可.') . "
"
; - $message .= __('如果需要重置密碼,請訪問下面的鏈接:') . "
"
; - $message .= tg_validate_url() . "action=reset_pwd&key=$key&login=" . rawurlencode($user_login) . "
"; //注意 tg_validate_url(),注意密碼重置的鏈接地址,需要 actionkeylogin 三個參數 - if ( $message && !wp_mail($user_email, '密碼重置請求', $message) ) {
- echo "<div > 郵件發送失敗-原因未知。</div>";
- exit();
- } else {
- echo "<div > 我們已經在給你發送的郵件中説明瞭重置密碼的各項事宜,請注意查收。</div>";
- exit();
- }
- } else {
- //輸出表單--第四步中的代碼應該包涵在這個對大括號內
- }
第七步:重置密碼
如果用户是通過重置密碼鏈接訪問本頁面,那麼 url 中會有 actionkeylogin 三個參數,通過 action 參數來獲取當前動作。
- if(isset($_GET['key']) && $_GET['action'] == "reset_pwd") { //如果存在 key 且 action 參數似乎 reset_pwd
- $reset_key = $_GET['key']; //獲取密匙
- $user_login = $_GET['login']; //獲取用户名
- $user_data = $wpdb->get_row($wpdb->prepare("SELECT ID, user_login, user_email FROM $wpdb->users WHERE user_activation_key = %s AND user_login = %s", $reset_key, $user_login));
- //通過 key 和用户名驗證數據
- $user_login = $user_data->user_login;
- $user_email = $user_data->user_email;
- if(!empty($reset_key) && !empty($user_data)) {
- $new_password = wp_generate_password(7, false); //生成 7 位隨機密碼
- //echo $new_password; exit();
- wp_set_password( $new_password, $user_data->ID ); //重置密碼
- //通過郵件將密碼發送給用户
- $message = __('賬户的新密碼為:') . "
"
; - $message .= get_option('siteurl') . "
"
; - $message .= sprintf(__('用户名: %s'), $user_login) . "
"
; - $message .= sprintf(__('密碼: %s'), $new_password) . "
"
; - $message .= __('你可以使用你的新密碼通過下面的鏈接登錄: ') . get_option('siteurl')."/login" . "
"
; - if ( $message && !wp_mail($user_email, '密碼重置請求', $message) ) {
- echo "<div > 郵件發送失敗-原因未知</div>";
- exit();
- } else {
- $redirect_to = tg_validate_url()."action=reset_success";//跳轉到登陸成功頁面 (還是本頁面地址)
- wp_safe_redirect($redirect_to);
- exit();
- }
- } else{
- exit('無效的 key.');
- }
- }
第八步:重置密碼成功
在上一步的代碼中,重置密碼成功則重定向到一個重置密碼成功的頁面,其實還是本頁面,只不多 action 參數不一樣:
- if(isset($_GET['action']) && $_GET['action'] == "reset_success") { //如果動作為 reset_success 就是成功了哇
- exit('<span class="success"> 密碼重置成功,已經通過郵件發送給您,請查收。</span>');
- }
到此,代碼已經完成。
下面是懶人下載
懶人下載-頁面模板文件
如果你想通過 url 重寫來實現本頁面,請注意更改相應的 「重置 url 函數」,以及一些涉及到 Url 的地方。