Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get current logged in user using Wordpress Rest Api?

Tags:

php

wordpress

I tried to add a custom request.

add_action('rest_api_init', function () {
    register_rest_route( 'custom', '/login', array(
        'methods' => 'GET',
        'callback' => function(WP_REST_Request $request) {
            return wp_get_current_user();
        }
    ));
});

But it always returns a user with with ID = 0; I also tried this:

add_action('rest_api_init', function () {
    register_rest_route( 'custom', '/login', array(
        'methods' => 'GET',
        'callback' => function(WP_REST_Request $request) {
            return is_user_logged_in();
        }
    ));
});

And it always returns false. But the user is logged in for sure.

I added my custom login

add_action('rest_api_init', function () {
    register_rest_route( 'custom', '/login', array(
        'methods' => 'POST',
        'callback' => function(WP_REST_Request $request) {
            $nonce = wp_create_nonce("wp_rest");
            $user = wp_signon(array('user_login' => $_POST['username'],
                'user_password' => $_POST['password'], "rememberme" => true), false);
            if (is_wp_error($user)) {
                return $user;
            }

            //do_action( 'wp_login', "capad" );
            //$user['isloggedin'] = is_user_logged_in();
            return array('user' => $user,
                'nonce' => $nonce);
        }
    ));
});

And I add "X-WP-Nonce" in as a header for http request

And now every request outputs: {"code":"rest_cookie_invalid_nonce","message":"Cookie nonce is invalid","data":{"status":403}}

like image 806
Semyon Avatar asked Feb 22 '17 02:02

Semyon


4 Answers

From the Authentication chapter, in the REST API Handbook:

Cookie authentication is the basic authentication method included with WordPress. When you log in to your dashboard, this sets up the cookies correctly for you, so plugin and theme developers need only to have a logged-in user.

However, the REST API includes a technique called nonces to avoid CSRF issues. This prevents other sites from forcing you to perform actions without explicitly intending to do so. This requires slightly special handling for the API.

For developers using the built-in Javascript API, this is handled automatically for you. This is the recommended way to use the API for plugins and themes. Custom data models can extend wp.api.models.Base to ensure this is sent correctly for any custom requests.

For developers making manual Ajax requests, the nonce will need to be passed with each request. The API uses nonces with the action set to wp_rest. These can then be passed to the API via the _wpnonce data parameter (either POST data or in the query for GET requests), or via the X-WP-Nonce header.

Here's a GET example:

https://example.tld/wp-json/wp/v2/users/me?_wpnonce=9467a0bf9c

or in your case:

https://example.tld/wp-json/custom/login/?_wpnonce=9463a0bf9c

where the nonce is created from

wp_create_nonce( 'wp_rest' );

So most likely you forgot about the nonce part when testing your custom endpoint.

Hope it helps!

like image 103
birgire Avatar answered Nov 07 '22 04:11

birgire


I spent two days searching for a simple way without adding plugins.

first in function.php where you define your api

//enqueue the script which will use the api
function api_callings_scripts() {
    wp_enqueue_script('score-script', get_template_directory_uri() . '/js/ScoreSaving.js', ['jquery'], NULL, TRUE);
    // Pass nonce to JS.
    wp_localize_script('score-script', 'ScoreSettings', [
      'nonce' => wp_create_nonce('wp_rest'),
    ]);
}
add_action( 'wp_enqueue_scripts', 'api_callings_scripts' ); 

Then your script Ajax call cloud be something like this

jQuery.ajax({
      type: "POST",
      url: "/wp-json/score/update",
      data: {"var1":"value1"},
      beforeSend: function(xhr) {
        xhr.setRequestHeader('X-WP-Nonce', ScoreSettings.nonce);
      },
    success: 
        function( data ) {
          console.log( data );
        }
    });

Now you can use get_current_user_id() inside your API code.

like image 32
Shady Mohamed Sherif Avatar answered Nov 07 '22 05:11

Shady Mohamed Sherif


1. Install and activate JWT Authentication for WP REST API plugin, also install WP REST API plugin
2. Now you can run any wordpress default api from mobile app or any other source or by postman. for example hit this url from your app or by postman. https://example.com/wp-json/wp/v2/posts
3. By app or by postman, When you will login with valid details (using rest api) you will get back a token. To login and get token, run the following url by postman or by app https://example.com/wp-json/jwt-auth/v1/token
4. By this way you will get a token as shown in picture postman and jwt authentication
Now use this token to get logged in user details, for example
5. make function in function.php

function checkloggedinuser()
{
$currentuserid_fromjwt = get_current_user_id();
print_r($currentuserid_fromjwt);
exit;
}

 add_action('rest_api_init', function ()
{
  register_rest_route( 'testone', 'loggedinuser',array(
  'methods' => 'POST',
  'callback' => 'checkloggedinuser'
  ));
}); 

6. Now again run this new url in postman or in app to get logged in user details. https://example.com/wp-json/testone/loggedinuser (replace example.com with your url) use of jwt token (https://i.stack.imgur.com/tIqhS.png)
7. Also edit your .htaccess file and wp-config.php file according to instructions on pt.wordpress.org/plugins/jwt-authentication-for-wp-rest-api

like image 9
shiv Avatar answered Nov 07 '22 04:11

shiv


If you prefer use JWT Authentication for WP REST API, it may be easier to implement with Json Web Tokens.

First you authenticate the client sending a HTTP POST request to the endpoint /wp-json/jwt-auth/v1/token sending username and password fields to generate a auth token.

A succefull response would be similar to:

{
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9qd3QuZGV2IiwiaWF0IjoxNDM4NTcxMDUwLCJuYmYiOjE0Mzg1NzEwNTAsImV4cCI6MTQzOTE3NTg1MCwiZGF0YSI6eyJ1c2VyIjp7ImlkIjoiMSJ9fX0.YNe6AyWW4B7ZwfFE5wJ0O6qQ8QFcYizimDmBy6hCH_8",
    "user_display_name": "admin",
    "user_email": "[email protected]",
    "user_nicename": "admin"
}

Then you pass the token each request settings the request header Authorization like:

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9qd3QuZGV2IiwiaWF0IjoxNDM4NTcxMDUwLCJuYmYiOjE0Mzg1NzEwNTAsImV4cCI6MTQzOTE3NTg1MCwiZGF0YSI6eyJ1c2VyIjp7ImlkIjoiMSJ9fX0.YNe6AyWW4B7ZwfFE5wJ0O6qQ8QFcYizimDmBy6hCH_8
like image 5
Gui Avatar answered Nov 07 '22 03:11

Gui