a_b
a_b

Reputation: 1918

How to get the Authorization header from request in wordpress

I'm trying to extract the Authorization header from an api request to an endpoint registered with register_rest_route, but it's not there.

I register a route:

register_rest_route('my_plugin', '/users', array(
    'methods' => 'PUT',
    'callback' => array($this, 'update_user'),
    )
);

simple dumb callback:

public function update_user($request)
{
    $all_headers = $request->get_headers();
    return new WP_REST_Response($all_headers, 200);
}

I then make a request to the endpoint where I make sure to set the Authorization header.

But header is missing in response:

{
  "host": ["localhost:8080"],
  "connection": ["keep-alive"],
  "content_length": ["23"],
  "accept": ["application/json, text/plain, */*"],
  "origin": ["http://localhost:8080"],
  "user_agent": [],
  "content_type": ["application/json;charset=UTF-8"],
  "referer": [
    "http://localhost:8080"
  ],
  "accept_encoding": ["gzip, deflate, br"],
  "accept_language": ["en-US,en;q=0.9"],
  "cookie": []
}

?

Upvotes: 1

Views: 7742

Answers (3)

Jaap De Jong
Jaap De Jong

Reputation: 41

Make sure your server actually has the HTTP authorization header enabled; in Apache site config or .htaccess:

RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

This should return the header:

$request->get_header('authorization')

Upvotes: 4

user8717003
user8717003

Reputation:

$request->get_headers() will not have the HTTP Authorization header because $request->set_headers() is done as follows:

$request->set_headers( $this->get_headers( wp_unslash( $_SERVER ) ) );

where $this is an instance of WP_REST_Server. But get_headers() of WP_REST_Server is defined in class-wp-rest-server.php as follows:

/**
 * Extracts headers from a PHP-style $_SERVER array.
 *
 * @since 4.4.0
 *
 * @param array $server Associative array similar to `$_SERVER`.
 * @return array Headers extracted from the input.
 */

public function get_headers( $server ) {
    $headers = array();

    // CONTENT_* headers are not prefixed with HTTP_.
    $additional = array( 'CONTENT_LENGTH' => true, 'CONTENT_MD5' => true, 'CONTENT_TYPE' => true );

    foreach ( $server as $key => $value ) {
        if ( strpos( $key, 'HTTP_' ) === 0 ) {
            $headers[ substr( $key, 5 ) ] = $value;
        } elseif ( isset( $additional[ $key ] ) ) {
            $headers[ $key ] = $value;
        }
    }

    return $headers;
}

So only members of the global $_SERVER with prefix '_HTTP' and the members 'CONTENT_LENGTH', 'CONTENT_MD5' and 'CONTENT_TYPE' are extracted. But the authorization members are 'PHP_AUTH_USER', 'PHP_AUTH_PW' and 'PHP_AUTH_DIGEST' in the $_SERVER global.

Upvotes: 4

janw
janw

Reputation: 6662

My main guess is that WP_Rest strips it later on. You can see the unfiltered results with:

public function update_user($request)
{
    echo json_encode($request->get_headers())
    exit;
}

If this does not help.
Send a random header, does that appear? You can send every header if it starts with x-

Upvotes: 0

Related Questions