首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从wp_rest返回的相同的rest_api

从wp_rest返回的相同的rest_api
EN

WordPress Development用户
提问于 2020-11-02 23:48:55
回答 1查看 820关注 0票数 2

AJAX TLDR:我如何强制返回一个新的

,以便AJAX在不刷新页面的情况下工作?

REST的Nonces和Ajax请求及其验证之后,我实现了现在的功能,具有回调权限,并且我的路由的“意图”现在是安全的。

我对Axios进行排队,使用wp_rest nonce作为本地脚本设置。

代码语言:javascript
运行
复制
    // 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头。

我的登录和退出路由示例:

代码语言:javascript
运行
复制
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错误.,但我的代码中没有任何东西可以改变用户并使现在的.

除非,登录路由--现在登录--更改了不返回的当前状态?

编辑

我用莎莉的答案重新分析了一下。所有工作(虽然我必须清除我的浏览器缓存,因为一些奇怪的事情正在发生)。

代码语言:javascript
运行
复制
    // 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',
    ));
});
EN

回答 1

WordPress Development用户

回答已采纳

发布于 2020-11-03 04:54:56

尽管你已经知道或者找到了一个解决方案,因为这是对另一个问题的跟进,我认为发布这个答案是有益的,所以希望它能对你有所帮助。=)

WordPress使用PHP中的本机setcookie()函数设置身份验证cookies,使用$_COOKIE读取cookies值。但问题是,PHP不会立即更新$_COOKIE数组中的值,而是只在页面重新加载后才会更新。

因此,由于WordPress不需要依赖当前用户和身份验证cookie,因此需要这样做才能在完全相同的页面/请求上获得正确的当前值--即不需要重新加载页面:

  1. 一旦调用了$_COOKIE (它调用了wp_set_auth_cookie()),立即更新wp_signon()数组。您可以使用set_logged_in_cookie钩子来实现这一点。
  2. 然后在登录用户之后调用wp_set_current_user() --如果您不调用它,生成的not将不使用当前用户,并且像is_user_logged_in()current_user_can()这样的函数也会返回false

工作示例

代码语言:javascript
运行
复制
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.
    ];
}

附加备注

  • REST端点的回调总是接收请求对象(一个WP_REST_Request实例)作为第一个参数,该参数除其他函数外,还有用于检索参数(如URL查询字符串、POST正文数据或JSON有效负载)的get_param(),因此您应该像我在示例中所做的那样,使用利用这个功能和其他功能。:)
票数 2
EN
页面原文内容由WordPress Development提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://wordpress.stackexchange.com/questions/377570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档