Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to set an authorisation header? #312

Closed
andreasvirkus opened this issue May 9, 2017 · 9 comments · Fixed by #315
Closed

How to set an authorisation header? #312

andreasvirkus opened this issue May 9, 2017 · 9 comments · Fixed by #315
Assignees

Comments

@andreasvirkus
Copy link

andreasvirkus commented May 9, 2017

Hi. I'm most likely getting something very basic wrong, but I can't put my finger on it.
I've got a JWT token that I'd like to set for my requests but superagent's set doesn't seem to work. Currently I get the following error:

TypeError: _endpoints2.default.pages(...).set is not a function

How would I go about setting the token? I saw headers in the docs, would that be it (and does it take an Object or something else)? Is there a way to set it for all requests by default (a custom transport maybe)?

import wp from './endpoints'; // I just export a new WPAPI() with some custom endpoints
import AuthService from './AuthenticationService';

let token = '';

AuthService.getAccessToken().then(webToken => {
    token = webToken;
});

export const getPages = () => wp.pages()
  .set('Authorization', 'Bearer ' + token)
  // .headers('Authorization', 'Bearer ' + token)  // How would the headers() format look?
  .param('per_page', '80')
  .then(response => {
    return response;
  }).catch(err => {
    console.log('ERR! Could not retrieve pages:', err);
  });
@andreasvirkus
Copy link
Author

andreasvirkus commented May 10, 2017

I found an example of .headers() from https://github.com/auth0/wp-jwt-auth/issues/1#issuecomment-268075628 and tried it out:

wp.pages()
  .param('per_page', '80')
  .headers({ authorization: 'Bearer ' + token })
  .then(...);

But the type of the request performed is now HEAD instead of GET, so the response body is missing.
In comparison, I've added a request for a custom endpoint where I didn't set the headers (remains of type GET)

HEAD /wp-json/wp/v2/pages?per_page=80 HTTP/1.1
Host: localhost:1234
User-Agent: node-superagent/3.5.2
Connection: close

GET /wp-json/wp-api-menus/v2/menu-locations/primary HTTP/1.1
Host: localhost:1234
Accept-Encoding: gzip, deflate
User-Agent: node-superagent/3.5.2
Connection: close

Edit: The auth headers aren't included in the request.

Edit 2: Seems I misunderstood the purpose of .headers() the first time around and it's there to perform HEAD requests. So my original question stands that how could I use the underlying superagent's .set() method to sign my requests with a token? I also tried adding https://github.com/rojo2/superagent-auth-bearer but just like .set(), it told me that
TypeError: _endpoints2.default.pages(...).param(...).authBearer is not a function
Is there a way for me to expose superagent somehow or apply a workaround?

@mzalewski
Copy link

I haven't really been keeping up with development, but you could look at creating a new HTTP Transport:
https://github.com/mzalewski/wpapi-oauth-example-transport

From memory, there's no easy way to set the headers. This may have changed recently though.

@mzalewski
Copy link

Alternatively, look at this pull request: #299
It's definitely cleaner than a new transport, but you'll have to use the forked version (until the pull request is merged)

@andreasvirkus
Copy link
Author

Excellent, thank you so much for pointing me towards that PR, @mzalewski. And sorry for hunting you down like that 😄

@mzalewski
Copy link

No problem, happy to help - let me know if you have any issues

@andreasvirkus
Copy link
Author

andreasvirkus commented May 16, 2017

@mzalewski Gonna poke you once more... Does it matter if I assign the JWT to the WP
instance:

const WP = new WPAPI({
  endpoint: process.env.WP_ENDPOINT,
  jwt: token
});

or if I attach it to every request (since I might not have it when creating the instance):

wp.pages()
  .param('per_page', '80')
  .auth({ jwt: token })
  .then(response => {
    return response;
  });

on Wordpress side I can't see any Authorization headers attached when I do
apache_request_headers()

@kadamwhite
Copy link
Collaborator

Hey y'all, apologies for letting this sit so long without response. We're evaluating supporting JWT natively but I will also be working on an update that includes a new method to set the headers to use on your request, which should make third-party support for JWT and other header-based authentication schemes much easier. I'll drop the PR link here for comments once I have something ready

@mzalewski
Copy link

That's great news 👍

@andreasvirkus I wouldn't think that you'd need to set it instance-wide - I haven't really tested it out though, so that's just based on my quick look at the pull request.

kadamwhite added a commit that referenced this issue May 17, 2017
In response to #299, #312, and #314, this introduces a new .setHeaders()
prototype method for both WPAPI and WPRequest. `.setHeaders()` allows a
single WPRequest, or all requests generated from a WPAPI site client
instance, to be augmented with one or more custom HTTP headers. Providing
this functionality allows consumers of the wpapi library to utilize
custom authentication schemes (such as JWT) with the Authentication
header, to specify the preferred language of the response endpoints with
the Accept-Language header, and so on. Providing a general-purpose
interface is preferred in place of specifically implementing individual
methods for JWT auth, language preferences, or other specific headers
that a consumer of this library may want to send.

Closes #299,

**Usage:**

If you need to send additional HTTP headers along with your request
(for example to provide a specific `Authorization` header for use with
alternative authentication schemes), you can use the `.setHeaders()`
method to specify one or more headers to send with the dispatched request:

```js
// Specify a single header to send with the outgoing request
wp.posts().setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' )...

// Specify multiple headers to send with the outgoing request
wp.posts().setHeaders({
    Authorization: 'Bearer xxxxx.yyyyy.zzzzz',
    'Accept-Language': 'pt-BR'
})...
```

You can also set headers on the WPAPI instance itself, which will then
be used for all subsequent requests created from that site instance:

```js
wp.setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' );
wp.users().me()...
wp.posts().id( unpublishedPostId )...
```
kadamwhite added a commit that referenced this issue May 17, 2017
In response to #299, #312, and #314, this introduces a new .setHeaders()
prototype method for both WPAPI and WPRequest. `.setHeaders()` allows a
single WPRequest, or all requests generated from a WPAPI site client
instance, to be augmented with one or more custom HTTP headers. Providing
this functionality allows consumers of the wpapi library to utilize
custom authentication schemes (such as JWT) with the Authentication
header, to specify the preferred language of the response endpoints with
the Accept-Language header, and so on. Providing a general-purpose
interface is preferred in place of specifically implementing individual
methods for JWT auth, language preferences, or other specific headers
that a consumer of this library may want to send.

Closes #299, fixes #312, fixes #314

**Usage:**

If you need to send additional HTTP headers along with your request
(for example to provide a specific `Authorization` header for use with
alternative authentication schemes), you can use the `.setHeaders()`
method to specify one or more headers to send with the dispatched request:

```js
// Specify a single header to send with the outgoing request
wp.posts().setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' )...

// Specify multiple headers to send with the outgoing request
wp.posts().setHeaders({
    Authorization: 'Bearer xxxxx.yyyyy.zzzzz',
    'Accept-Language': 'pt-BR'
})...
```

You can also set headers on the WPAPI instance itself, which will then
be used for all subsequent requests created from that site instance:

```js
wp.setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' );
wp.users().me()...
wp.posts().id( unpublishedPostId )...
```
@kadamwhite kadamwhite self-assigned this May 17, 2017
@kadamwhite
Copy link
Collaborator

@mzalewski @andreasvirkus I've proposed a system for specifying custom headers in pull request #315 and I would welcome your feedback on the implementation and interface.

kadamwhite added a commit that referenced this issue May 18, 2017
)

* Implement a `.setHeaders()` method for WPAPI and WPRequest objects

In response to #299, #312, and #314, this introduces a new .setHeaders()
prototype method for both WPAPI and WPRequest. `.setHeaders()` allows a
single WPRequest, or all requests generated from a WPAPI site client
instance, to be augmented with one or more custom HTTP headers. Providing
this functionality allows consumers of the wpapi library to utilize
custom authentication schemes (such as JWT) with the Authentication
header, to specify the preferred language of the response endpoints with
the Accept-Language header, and so on. Providing a general-purpose
interface is preferred in place of specifically implementing individual
methods for JWT auth, language preferences, or other specific headers
that a consumer of this library may want to send.

Closes #299, fixes #312, fixes #314

**Usage:**

If you need to send additional HTTP headers along with your request
(for example to provide a specific `Authorization` header for use with
alternative authentication schemes), you can use the `.setHeaders()`
method to specify one or more headers to send with the dispatched request:

```js
// Specify a single header to send with the outgoing request
wp.posts().setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' )...

// Specify multiple headers to send with the outgoing request
wp.posts().setHeaders({
    Authorization: 'Bearer xxxxx.yyyyy.zzzzz',
    'Accept-Language': 'pt-BR'
})...
```

You can also set headers on the WPAPI instance itself, which will then
be used for all subsequent requests created from that site instance:

```js
wp.setHeaders( 'Authorization', 'Bearer xxxxx.yyyyy.zzzzz' );
wp.users().me()...
wp.posts().id( unpublishedPostId )...
```

props to @anagio, @andreasvirkus, @gnarf, @Matthewnie, @mnivoliez,
and @mzalewski for the feature request, feedback & discussion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants