AJAX TLDR:我如何强制返回一个新的
在REST的Nonces和Ajax请求及其验证之后,我实现了现在的功能,具有回调权限,并且我的路由的“意图”现在是安全的。
我对Axios进行排队,使用wp_rest nonce作为本地脚本设置。
// Register custom variables for the AJAX script.
wp_localize_script( 'axios', 'axiosScriptVars', [
'root' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' ),
]);我用axiosScriptVars.nonce设置了Ajax头。我贴了-这个很管用。我从我的REST_API端点的响应中返回一个NONCE,并为下一篇文章更新我的Ajax头。
我的登录和退出路由示例:
function ajax_logout() {
try {
wp_logout();
$nonce = wp_create_nonce( 'wp_rest' );
return array('loggedin'=>false, 'message'=>__('Logged out successfully'), 'name'=>false, 'email'=>false, 'nonce'=>$nonce );
} catch (Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
die;
}
}
function ajax_login(){
$_POST = json_decode(file_get_contents("php://input"),true);
$info = array();
$info['user_login'] = !empty($_POST['username']) ? sanitize_text_field( $_POST['username'] ) : null;
$info['user_password'] = !empty( $_POST['password'] ) ? sanitize_text_field( $_POST['password'] ) : null;
$info['remember'] = true;
$user = wp_signon( $info, true );
$nonce = wp_create_nonce( 'wp_rest' );
if ( is_wp_error($user) ){
return array('loggedin'=>false, 'message'=>__('Wrong username or password.'), 'name'=>false, 'email'=>false, 'nonce'=>$nonce );
} else {
return array('loggedin'=>true, 'message'=>__('Login successful'), 'name'=>$user->data->display_name, 'email'=>$user->data->user_email, 'nonce'=>$nonce );
}
}
add_action( 'rest_api_init', function () {
register_rest_route( 'rw-user/v1', '/log-in', array(
'methods' => 'POST',
'callback' => 'ajax_login',
'permission_callback' => '__return_true'
));
register_rest_route('rw-user/v1','/log-out', array(
'methods' => 'POST',
"callback" => 'ajax_logout',
"permission_callback" => function () {
return current_user_can( 'read' );
}
));
});发布失败,因为新的现在和旧的相同。
所以我想Wordpress必须在回复头上返回一个新的nonce .我检查和看到的“x-wp”的标题-只是它也是相同的!
(我读到了一些关于在REST路由中不使用wp_json_success的内容,因为rest已经将函数的返回转换为json响应,并设置了正确的标头等等。)
当我努力刷新页面时,我得到了一个新的版本,而我的AJAX现在开始工作了.
如何强制返回一个新的nonce,以便AJAX在不刷新页面的情况下工作?
这篇文章有点类似- 通过AJAX提供服务不刷新当前状态,返回403错误.,但我的代码中没有任何东西可以改变用户并使现在的.
除非,登录路由--现在登录--更改了不返回的当前状态?
编辑
我用莎莉的答案重新分析了一下。所有工作(虽然我必须清除我的浏览器缓存,因为一些奇怪的事情正在发生)。
// https://wordpress.stackexchange.com/questions/377570/identical-wp-rest-nonce-returned-from-rest-api
/* Ajax REST cookie stuff */
// https://remonpel.nl/2018/06/wordpress-rest-api-nonce-sense/
add_action('set_logged_in_cookie', function($cookie_value){
$_COOKIE[ LOGGED_IN_COOKIE ] = $cookie_value;
}, PHP_INT_MAX);
// on log-ou, clear the global $_COOKIE the same way wp_logout() does.
// todo: see if more cookies need this.
add_action('clear_auth_cookie', function(){
$_COOKIE[ LOGGED_IN_COOKIE ] = ' ';
});
/* end Ajax REST cookie stuff */
function ajax_logout() {
wp_logout();
wp_set_current_user(0);
return [
'loggedin' => false,
'message' => __('Logged out successfully'),
'name' => false,
'email' => false,
];
}
function ajax_login($request){
$user = wp_signon( array(
'user_login' => $request->get_param( 'username' ),
'user_password' => $request->get_param( 'password' ),
'remember' => true,
));
// In case of errors like wrong password, return the error object/data.
if ( is_wp_error( $user ) ) {
$data = [
'failed' => $user,
'nonce' => wp_create_nonce( 'wp_rest' ),
];
return new WP_REST_Response($data, 200); // important if you want to display data client side
}
wp_set_current_user( $user->ID ); // super important
return [
'loggedin' => is_user_logged_in(),
'message' => __('Login successful'),
'name' => $user->data->display_name,
'email' => $user->data->user_email,
'nonce' => wp_create_nonce( 'wp_rest' ),
];
}
function read_permissions_check() {
// Restrict endpoint to only users who have the edit_posts capability.
// This can be extended or whatever
if ( !current_user_can( 'read' ) ) {
return new WP_Error( 'rest_forbidden', esc_html__( 'You shall not pass!', 'my-text-domain' ), array( 'status' => 401 ) );
}
return true;
}
add_action( 'rest_api_init', function () {
register_rest_route( 'rw-user/v1', '/log-in', array(
'methods' => 'POST',
'callback' => 'ajax_login',
'permission_callback' => '__return_true',
));
register_rest_route('rw-user/v1','/log-out', array(
'methods' => 'POST',
"callback" => 'ajax_logout',
'permission_callback' => 'read_permissions_check',
));
});发布于 2020-11-03 04:54:56
尽管你已经知道或者找到了一个解决方案,因为这是对另一个问题的跟进,我认为发布这个答案是有益的,所以希望它能对你有所帮助。=)
WordPress使用PHP中的本机setcookie()函数设置身份验证cookies,使用$_COOKIE读取cookies值。但问题是,PHP不会立即更新$_COOKIE数组中的值,而是只在页面重新加载后才会更新。
因此,由于WordPress不需要依赖当前用户和身份验证cookie,因此需要这样做才能在完全相同的页面/请求上获得正确的当前值--即不需要重新加载页面:
$_COOKIE (它调用了wp_set_auth_cookie()),立即更新wp_signon()数组。您可以使用set_logged_in_cookie钩子来实现这一点。wp_set_current_user() --如果您不调用它,生成的not将不使用当前用户,并且像is_user_logged_in()和current_user_can()这样的函数也会返回false。function wpse_377570( $logged_in_cookie ) {
$_COOKIE[ LOGGED_IN_COOKIE ] = $logged_in_cookie;
}
add_action( 'set_logged_in_cookie', 'wpse_377570' );
function ajax_login( $request ) {
// Logs the user in and set the authentication cookies.
$user = wp_signon( array(
'user_login' => $request->get_param( 'username' ),
'user_password' => $request->get_param( 'password' ),
'remember' => true,
) );
// In case of errors like wrong password, return the error object/data.
if ( is_wp_error( $user ) ) {
return $user;
}
// Now set the current user so that we get the correct nonce based on
// that user.
wp_set_current_user( $user->ID );
return [
'nonce' => wp_create_nonce( 'wp_rest' ),
'loggedin' => is_user_logged_in(),
// ... your other data.
];
}WP_REST_Request实例)作为第一个参数,该参数除其他函数外,还有用于检索参数(如URL查询字符串、POST正文数据或JSON有效负载)的get_param(),因此您应该像我在示例中所做的那样,使用利用这个功能和其他功能。:)https://wordpress.stackexchange.com/questions/377570
复制相似问题