Google에서 온 사용자의 경우 : 실제로 수행중인 작업을 모르면 REST API에서 nonces를 가져 오지 않아야합니다 . 나머지 API를 사용하여 쿠키 기반 인증 전용 의미 플러그인과 테마에 대해. 단일 페이지 애플리케이션의 경우 OAuth 를 사용해야합니다 .
이 질문은 단일 페이지 앱을 빌드 할 때 실제로 어떻게 인증해야하는지, JWT가 웹 앱에 적합하지 않으며, OAuth가 쿠키 기반 인증보다 구현하기가 어렵다는 문서가 명확하지 않거나 명확하지 않기 때문에 존재합니다.
핸드북 에는 Backbone JavaScript 클라이언트가 nonces를 처리하는 방법에 대한 예제가 있으며이 예제를 따르면 / wp / v2 / posts와 같은 내장 엔드 포인트가 수락하는 nonce를 얻습니다.
\wp_localize_script("client-js", "theme", [
'nonce' => wp_create_nonce('wp_rest'),
'user' => get_current_user_id(),
]);
그러나 Backbone을 사용하는 것은 의문의 여지가 없으며 테마도 마찬가지이므로 다음 플러그인을 작성했습니다.
<?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 콘솔에서 조금만 살펴보고 다음과 같이 썼습니다.
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()
예상 결과는 두 개의 새 게시물이지만 Cookie nonce is invalid
첫 번째 게시물에서 가져 오고 두 번째 게시물은 성공적으로 게시물을 만듭니다. 아마도 nonces가 다르기 때문일 것입니다. 왜 그렇습니까? 두 요청 모두에 동일한 사용자로 로그인했습니다.
내 접근 방식이 잘못되면 nonce를 어떻게 받아야합니까?
편집 :
나는 많은 운이없이 지구본을 망치려고 노력했다 . wp_loaded 액션을 사용하여 조금 더 운이 좋았습니다.
<?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,
];
},
]);
});
위의 JavaScript를 실행하면 두 개의 게시물이 작성되지만 엔드 포인트 확인에 실패합니다!
나는 wp_verify_nonce를 디버깅하러 갔다.
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!
로깅을 추가했습니다.
// 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;
}
JavaScript 코드는 이제 다음 항목을 생성합니다. 보시다시피, 검증 엔드 포인트가 호출 될 때 uid는 0입니다.
[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