2012-06-03 9 views
2

Smart Wordpress people say插件開發人員應該在從頁面發送回wordpress博客(admin-ajax.php)的每個AJAX請求中使用隨機數。check_ajax_referer()如何工作?

這是通過(1)生成在服務器端隨機數經由

$nonce = wp_create_nonce ('my-nonce'); 

...(2),使得提供給發送AJAX請求JavaScript代碼,隨機數完成。例如,你可以做這樣的:

function myplg_emit_scriptblock() { 
    $nonce = wp_create_nonce('myplg-nonce'); 
    echo "<script type='text/javascript'>\n" . 
     " var WpPlgSettings = {\n" . 
     " ajaxurl : '" . admin_url('admin-ajax.php') . "',\n" . 
     " nonce : '" . $nonce . "'\n" . 
     " };\n" . 
     "</script>\n"; 
} 
add_action('wp_print_scripts','myplg_emit_scriptblock'); 

...然後(3)的JavaScript AJAX邏輯引用全局變量。

var url = WpPlgSettings.ajaxurl + 
     "?action=my-wp-plg-action&" + 
     "nonce=" + WpPlgSettings .nonce + 
     "docid=" + id; 

    $.ajax({type: "GET", 
      url: url, 
      headers : { "Accept" : 'application/json' }, 
      dataType: "json", 
      cache: false, 
      error: function (xhr, textStatus, errorThrown) { 
       ... 
      }, 
      success: function (data, textStatus, xhr) { 
       ... 
      } 
      }); 

......最後(4)檢查服務器端邏輯中接收到的nonce。

add_action('wp_ajax_nopriv_skydrv-hotlink', 'myplg_handle_ajax_request'); 
add_action('wp_ajax_skydrv-hotlink', 'myplg_handle_ajax_request'); 
function myplg_handle_ajax_request() { 
    check_ajax_referer('myplg-nonce', 'nonce'); // <<=----- 
    if (isset($_GET['docid'])) { 
     $docid = $_GET['docid']; 
     $response = myplg_generate_the_response($docid); 
     header("Content-Type: application/json"); 
     echo json_encode($response) ; 
    } 
    else { 
     $response = array("error" => "you must specify a docid parameter."); 
     echo json_encode($response) ; 
    } 

    exit; 
} 

但是檢查真的有效嗎?

回答

12

Revising some AJAX procedures,我來到同一個問題。和它的檢查function code一個簡單的問題:

function check_ajax_referer($action = -1, $query_arg = false, $die = true) { 
    if ($query_arg) 
     $nonce = $_REQUEST[$query_arg]; 
    else 
     $nonce = isset($_REQUEST['_ajax_nonce']) ? $_REQUEST['_ajax_nonce'] : $_REQUEST['_wpnonce']; 

    $result = wp_verify_nonce($nonce, $action); 

    if ($die && false == $result) { 
     if (defined('DOING_AJAX') && DOING_AJAX) 
      wp_die(-1); 
     else 
      die('-1'); 
    } 

    do_action('check_ajax_referer', $action, $result); 

    return $result; 
} 

如果wp_verify_noncefalse,你有沒有在$die參數發送false,那麼它會執行wp_die(-1);


在你的示例代碼,check_ajax_referer()將打破執行和返回-1到AJAX調用。如果你想自己處理錯誤,添加參數$die,做你的東西與$do_check

$do_check = check_ajax_referer('myplg-nonce', 'nonce', false); 

注意處理AJAX在WordPress的正確方法是:registerenqueuelocalize JavaScript文件使用wp_enqueue_scripts而不是wp_print_scripts
請參閱Use wp_enqueue_scripts() not wp_print_styles()

+0

您即將獲得徽章,因爲我會在發佈問題14個月後接受您的回答。謝謝! – Cheeso

+0

我認爲徽章是在有兩個upvotes時出現的;)很高興看到一個老Q正在解決,歡迎您! – brasofilo

0

這只是一個測試,「nonce」代碼與給定的代碼匹配,所以黑客無法切入並獲得數據庫的快捷方式。如果安全代碼不匹配,php將會死亡,頁面將停止。 「如果你的代碼被正確驗證了,它會繼續過去,如果沒有,它會觸發die(' - 1');停止你的代碼死掉。」