Google'dan gelenler için: Ne yaptığınızı gerçekten bilmiyorsanız , büyük olasılıkla REST API'sından nonces almamalısınız . REST API ile Çerez tabanlı kimlik doğrulaması okunur anlamına eklentileri ve temaları. Tek sayfalık bir uygulama için muhtemelen OAuth kullanmalısınız .
Bu soru, tek sayfalı uygulamalar oluştururken gerçekte nasıl kimlik doğrulaması yapmanız gerektiği konusunda dokümantasyonun açık olmadığı / açık olmadığı, JWT'lerin web uygulamaları için gerçekten uygun olmadığı ve OAuth'un çerez tabanlı kimlik doğrulamasından daha zor uygulandığı için var.
El kitabının , Omurga JavaScript istemcisinin nonces'i nasıl işlediğine dair bir örneği var ve örneği takip edersem, / wp / v2 / posts gibi yerleşik uç noktaların kabul ettiği bir nonce alıyorum.
\wp_localize_script("client-js", "theme", [
'nonce' => wp_create_nonce('wp_rest'),
'user' => get_current_user_id(),
]);
Ancak, Backbone kullanmak söz konusu değildir ve temalar da öyle, bu yüzden aşağıdaki eklentiyi yazdım:
<?php
/*
Plugin Name: Nonce Endpoint
*/
add_action('rest_api_init', function () {
$user = get_current_user_id();
register_rest_route('nonce/v1', 'get', [
'methods' => 'GET',
'callback' => function () use ($user) {
return [
'nonce' => wp_create_nonce('wp_rest'),
'user' => $user,
];
},
]);
register_rest_route('nonce/v1', 'verify', [
'methods' => 'GET',
'callback' => function () use ($user) {
$nonce = !empty($_GET['nonce']) ? $_GET['nonce'] : false;
return [
'valid' => (bool) wp_verify_nonce($nonce, 'wp_rest'),
'user' => $user,
];
},
]);
});
JavaScript konsolunda biraz uğraştım ve aşağıdakileri yazdım:
var main = async () => { // var because it can be redefined
const nonceReq = await fetch('/wp-json/nonce/v1/get', { credentials: 'include' })
const nonceResp = await nonceReq.json()
const nonceValidReq = await fetch(`/wp-json/nonce/v1/verify?nonce=${nonceResp.nonce}`, { credentials: 'include' })
const nonceValidResp = await nonceValidReq.json()
const addPost = (nonce) => fetch('/wp-json/wp/v2/posts', {
method: 'POST',
credentials: 'include',
body: JSON.stringify({
title: `Test ${Date.now()}`,
content: 'Test',
}),
headers: {
'X-WP-Nonce': nonce,
'content-type': 'application/json'
},
}).then(r => r.json()).then(console.log)
console.log(nonceResp.nonce, nonceResp.user, nonceValidResp)
console.log(theme.nonce, theme.user)
addPost(nonceResp.nonce)
addPost(theme.nonce)
}
main()
Beklenen sonuç iki yeni gönderi, ancak Cookie nonce is invalid
birinciden alıyorum ve ikincisi gönderiyi başarıyla yaratıyor. Muhtemelen nonces farklı olduğu için, ama neden? Her iki istekte de aynı kullanıcı olarak oturum açtım.
Yaklaşımım yanlışsa, nonce'yi nasıl edinmeliyim?
Düzenle :
Ben globaller karıştırmasını çalıştı çok şans olmadan . Wp_loaded eylemini kullanarak biraz şanslı var:
<?php
/*
Plugin Name: Nonce Endpoint
*/
$nonce = 'invalid';
add_action('wp_loaded', function () {
global $nonce;
$nonce = wp_create_nonce('wp_rest');
});
add_action('rest_api_init', function () {
$user = get_current_user_id();
register_rest_route('nonce/v1', 'get', [
'methods' => 'GET',
'callback' => function () use ($user) {
return [
'nonce' => $GLOBALS['nonce'],
'user' => $user,
];
},
]);
register_rest_route('nonce/v1', 'verify', [
'methods' => 'GET',
'callback' => function () use ($user) {
$nonce = !empty($_GET['nonce']) ? $_GET['nonce'] : false;
error_log("verify $nonce $user");
return [
'valid' => (bool) wp_verify_nonce($nonce, 'wp_rest'),
'user' => $user,
];
},
]);
});
Şimdi yukarıdaki JavaScript'i çalıştırdığımda iki gönderi oluşturuldu, ancak doğrulama uç noktası başarısız!
Wp_verify_nonce hata ayıklamaya gittim:
function wp_verify_nonce( $nonce, $action = -1 ) {
$nonce = (string) $nonce;
$user = wp_get_current_user();
$uid = (int) $user->ID; // This is 0, even though the verify endpoint says I'm logged in as user 2!
Biraz giriş ekledim
// Nonce generated 0-12 hours ago
$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10 );
error_log("expected 1 $expected received $nonce uid $uid action $action");
if ( hash_equals( $expected, $nonce ) ) {
return 1;
}
// Nonce generated 12-24 hours ago
$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
error_log("expected 2 $expected received $nonce uid $uid action $action");
if ( hash_equals( $expected, $nonce ) ) {
return 2;
}
ve JavaScript kodu şimdi aşağıdaki girişlerle sonuçlanır. Gördüğünüz gibi, doğrulama bitiş noktası çağrıldığında uid 0 olur.
[01-Mar-2018 11:41:57 UTC] verify 716087f772 2
[01-Mar-2018 11:41:57 UTC] expected 1 b35fa18521 received 716087f772 uid 0 action wp_rest
[01-Mar-2018 11:41:57 UTC] expected 2 dd35d95cbd received 716087f772 uid 0 action wp_rest
[01-Mar-2018 11:41:58 UTC] expected 1 716087f772 received 716087f772 uid 2 action wp_rest
[01-Mar-2018 11:41:58 UTC] expected 1 716087f772 received 716087f772 uid 2 action wp_rest