WP REST API how to check header basic authentication - wordpress

A custom endpoint like this
add_action( 'rest_api_init', function () {
register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'my_awesome_func',
) );
} );
Using basic authentication in headers, let's say 'Authorization: Basic some64basePass'
How I can check the value of Authorization in the header is valid or not?

Here is my solution.
Inside the callback function I validate Authorization from the header like this:
function my_awesome_func($data) {
//Get HTTP request headers
$auth = apache_request_headers();
//Get only Authorization header
$valid = $auth['Authorization'];
// Validate
if ($valid == 'Basic Base64UsernamePassword') {
//Do what the function should do
} else {
$response = 'Please use a valid authentication';
}
return json_encode($response);
}
Maybe there is a better way.

WordPress has a hook for adding your own authentication handler.
add_filter( 'rest_authentication_errors', 'rest_basic_auth_check_errors', 99 );
Your rest_basic_auth_check_errors() should return true if basic authentication succeeds or WP_Error if it fails. Since the default REST authentication handler runs at priority 100 your rest_basic_auth_check_errors() will override the default handler.
See the function WP_REST_Server::check_authentication() in file ...\wp-includes\rest-api\class-wp-rest-server.php to understand how WordPress handles REST authentication and how to add your own authentication handler.
Also, you should read about $_SERVER['PHP_AUTH_USER'] and $_SERVER['PHP_AUTH_PW'] in http://php.net/manual/en/features.http-auth.php

Related

Wordpress REST Api: add_action( 'rest_api_init', callback) does not call the callback

Problem:
I'm trying to register a custom endpoint for a Wordpress plugin. The problem I face is that when I call the add_action('rest_api_init', callback), the callback function is not being called. In that callback function lives the "register_rest_route()" method, which in it's turn is not being called and I am unable to register any custom endpoints.
I'm using docker for development
No errors are being thrown
Code:
public function register()
{
$this->setup_init();
}
public function setup_init()
{
var_dump('print1');
add_action('rest_api_init', array($this, 'register_custom_endpoints'));
}
public function register_custom_endpoints()
{
var_dump('print2');
die();
register_rest_route('test', '/test', array(
'methods' => 'GET',
'callback' => 'menu_setup',
));
}
Question:
The code reaches the "var_dump('print1')", but the the "var_dump('print2')" is never reached. Am I missing something here?
After trying many options I found out that changing: "Setting -> permalinks -> common settings" to anything else then the option "Plain" solved the issue. The callback method is now being reached, and my custom endpoints are being registered.

How to enable https for wordpress and install certificate

I have been able to create a custom endpoint following the code below for wordpress
function handle_woocommerce_keys($request){
$user_id = $request[user_id];
$consumer_key=$request[consumer_key];
$consumer_secret=$request[consumer_secret];
$key_permissions=$request[key_permissions];
/* search user_id in db and store the keys as meta_data */
$response = new WP_REST_Response();
$response->set_status(200);
return $response;
}
add_action('rest_api_init', function () {
register_rest_route( 'village/v1', 'authkeys',array(
'methods' => 'POST',
'callback' => 'handle_woocommerce_keys'
));
});
Unfortunatly it's only working using HTTP. I use Postman and it behave has expected. However, I need HTTPS to be supported. The reason is that the endpoint URL is provide as param to a server and used by this server to send a POST to this https URL.
Any idea how to make HTTPS endpoint supported on Wordpress ?
Do I need to install a certificate, If yes how ?
Thanks

Get current user inside register_rest_route method

How to retrive wp_get_current_user() inside a register_rest_route callback (Wordpress site)?
I'm just trying to do a simple hello wp_get_current_user()->user_login on a php test page:
add_action('rest_api_init', 'helloTest');
function helloTest() {
register_rest_route('hello', 'hello/(?P<id>\d+)', array(
'methods' => WP_REST_SERVER::READABLE,
'callback' => 'showHello'
));
}
function showHello($someVariable) {
echo "Hello " . wp_get_current_user()->user_login . $someVariable;
}
But wp_get_current_user() is null and wp_get_current_user->ID is 0;
I dont want to authenticate the user again. I just want to retrieve his username. If he is not logged in, just show empty an empty string.
If I have to authenticate again, how to add a "nonce" to it? On internet I just have examples using javascript, but not directly on PHP methods.
Issues in your code
First off, you should understand properly how to add custom WP REST API endpoints:
An endpoint's namespace (the first parameter passed to register_rest_route()) should be in this format: your-plugin/v<version>. E.g. hello/v1 or hello-world/v1 and not just hello or hello-world.
$someVariable (the first parameter passed to your endpoint callback function) is not just any variable — it's an instance of the WP_REST_Request class — and shouldn't be echo-ed like what you did here:
function showHello($someVariable) {
echo "Hello " . wp_get_current_user()->user_login . $someVariable;
}
And normally, the $someVariable is better be changed to $request (i.e. rename it to "request").
And you should return a valid WP REST API response. For example, to return just the username:
return new WP_REST_Response( wp_get_current_user()->user_login, 200 );
And know your own API endpoint URL..
(based on your original namespace)
/wp-json/hello/hello/1 <- correct
/wp-json/hello/?John <- incorrect
because in your code, the parameter is a number and not string: (?P<id>\d+)
I hope those help you, and once again, do read the handbook for a more detailed guide.
The Corrected Code
add_action( 'rest_api_init', 'helloTest' );
function helloTest() {
register_rest_route( 'hello/v1', 'hello/(?P<id>\d+)', array(
'methods' => WP_REST_SERVER::READABLE,
'callback' => 'showHello'
) );
}
function showHello( $request ) {
return new WP_REST_Response( wp_get_current_user()->user_login, 200 );
}
Now about getting the user (from the API endpoint — showHello())
If I have to authenticate again, how to add a "nonce" to it?
Just because the user is logged-in/authenticated to the (WordPress) site, it doesn't mean the user is automatically logged-in to the WP REST API. So yes, you'd need to either provide a nonce along with your API request, or use one of the authentication plugins mentioned right here.
Now in most cases, GET (i.e. read-only) requests to the API do not need any authentication, but if you'd like to retrieve the data of the currently logged-in user on your site, then one way is via the _wpnonce data parameter (either POST data or in the query for GET requests).
Example for a GET request:
http://example.com/wp-json/wp/v2/posts?_wpnonce=<nonce>
So based on your comment and the corrected code (above):
Theres no "code" that make the request. Its is just an anchor that
calls my route: Hello
You can add the nonce as part of the URL query string like so: (the namespace is hello/v1 and the <id> is 1)
// Make request to /wp-json/hello/v1/hello/<id>
$nonce = wp_create_nonce( 'wp_rest' );
echo 'Hello';
So try that out along with the corrected code and let me know how it goes. :)
And once again, be sure to read the REST API authentication handbook.

How to get current logged in user from WordPress via custom endpoints?

I have an endpoint in my WordPress plugin, and using it. I want to get the user who is currently logged in the WordPress. My endpoint looks like this:
add_action( 'rest_api_init', function () {
register_rest_route( 't2mchat/v2', '/get_curr_user', array(
'methods' => 'GET',
'callback' => 'get_curr_user'
));
});
The callback function:
function get_curr_user(WP_REST_Request $request){
$user = wp_get_current_user();
return $user;
}
This gives me back user ID as 0.
I read the article on WordPress official website about Authentication , and learned that I need to pass nonces, but since I am a new to this, I could not understand everything it says.
Also, I am calling this endpoint in my React app like this:
loadData() {
return fetch(`/wordpress/wp-json/t2mchat/v2/get_curr_user`)
.then(response => response.json())
.then(responseJson => {
this.setState({ curr_user: responseJson });
//console.log(this.state.curr_user, "curr user role");
})
.catch(error => {
console.error(error);
});
}
I am not sure how do I pass nonces in the request, so I can get the currently logged in user.
Can anyone with experience/idea suggest what changes I need to make in my code?
An example would be highly appreciated.
Thank you.
in your PHP file include the wp-load.php
include_once("wp-load.php");
then you can access to all native Wordpress Function just call them.
So you have to be able to retrieve the current logged in user by wp_get_current_user();
I used session storage to store user data when the wordpress initializes and retrieved from my endpoint. It worked for me.

Facebook post wirth php error: (#200) The user hasn't authorized the application to perform this action

i want to post from my website to my facebook site. i have created a app for my site. I use this code (i replace data from my app with '[]'):
require_once 'lib/php-graph-sdk-5.4/src/Facebook/autoload.php';
// initialize Facebook class using your own Facebook App credentials
// see: https://developers.facebook.com/docs/php/gettingstarted/#install
$access_token = '[aaccesstoken]';
$config = array();
$config['app_id'] = '[appid]';
$config['app_secret'] = '[appsecret]';
$config['fileUpload'] = false; // optional
$fb = new \Facebook\Facebook($config);
// define your POST parameters (replace with your own values)
$params = array(
"access_token" => $access_token, // see: https://developers.facebook.com/docs/facebook-login/access-tokens/
"message" => "Test Message",
"link" => "http://www.frauen-styles.de",
"picture" => "http://www.frauen-styles.de/site/assets/files/3545/20.jpg",
"name" => "Test Name",
"caption" => "Caption",
"description" => "Beschreibung"
);
// post to Facebook
// see: https://developers.facebook.com/docs/reference/php/facebook-api/
try {
$ret = $fb->post('/me/feed', $params);
echo 'Successfully posted to Facebook';
} catch(Exception $e) {
echo $e->getMessage();
}
what i'm doing wrong? im administrator of the page. support tells me that no publish_pages is requiered for the app for admins. I only want to send a post from my website to my facebook-page.
support tells me that no publish_pages is requiered
As you can read in the API reference in the official docs, you do need publish_pages and manage_pages to post to a Page (as Page).
Docs: https://developers.facebook.com/docs/graph-api/reference/page/feed#publish

Resources