Skip to content
This repository has been archived by the owner on Nov 4, 2019. It is now read-only.

add support for wp-api v2 #1

Closed
ddbaron opened this issue Dec 23, 2015 · 26 comments
Closed

add support for wp-api v2 #1

ddbaron opened this issue Dec 23, 2015 · 26 comments

Comments

@ddbaron
Copy link

ddbaron commented Dec 23, 2015

@glena having issues getting this to work with v2 of the wp-api

The following WORKS:

  1. Wordpress 4.4
  2. Wordpress Auth0 Integration 1.3.6
  3. Wordpress JWT Authentication 1.1.1
  4. WP REST API 1.2.4

The following does NOT WORK:

  1. wordpress 4.4
  2. Wordpress Auth0 Integration 1.3.6
  3. Wordpress JWT Authentication 1.1.1
  4. WP REST API 2.0-beta9

Issues:

  1. http://<domain>/wp-json/wp/v2/users/me results in:
{
code: "rest_not_logged_in",
message: "You are not currently logged in.",
data: {
status: 401
}
}
  1. Issuing a POST to http://<domain>/wp-json/wp/v2/posts doesn't work. I've confirmed the Authorization:Bearer is there and correct:
{"code":"rest_forbidden","message":"You don't have permission to do this.","data":{"status":403}}

Lastly, perhaps this will accelerate your understanding of the issue: Tmeister/wp-api-jwt-auth#6 (comment) --> seems to imply the cookie testing is overriding the JWT, at least for this plugin....

@glena
Copy link
Contributor

glena commented Dec 28, 2015

Thanks for reporting, will check the changes on v2 and try to release a new version depending on how mature it is (I want to avoid rework for BC issues due to changes between beta releases)

@moneal
Copy link
Contributor

moneal commented Apr 26, 2016

Any update on this?

@glena
Copy link
Contributor

glena commented May 3, 2016

@moneal not yet. The plugin is still in beta, and TBH I wasn't able to check what changed. If you can provide me some insights on what needs to be changed, I can push this release sooner (also PR are always welcome).

Thx

@glena
Copy link
Contributor

glena commented May 10, 2016

@ddbaron @moneal

I am checking this issue, and seems to be working fine to me.

Versions:

  • wp-jwt-auth: Version 1.1.1
  • rest-api (wp-api): Version 2.0-beta13
  • auth0: Version 2.1.11

Repro steps:

  1. I had auth0 working configured before this, then installed wp-api and wp-jwt-auth.
  2. Enabled auth0 to provision wp-jwt-auth.
  3. Get a user id_token.
  4. Set this user role in wordpress as author.
  5. Call POST /wp-json/wp/v2/posts.
  6. The post was created

Posible issues:

  • Wrong user role
  • Apache naming the Authorization header differently (it would depend on your configuration).
    To fix this, you can add a var_dump here.
    On line 31: var_dump('getallheaders ',$headers);exit; and under line 37: var_dump('$_SERVER ',$_SERVER);exit;. After that depending on what the server answers in the request, check if the header name matches the way it tries to get it in there and change its name (and let me know so I can release a new versions checking for both names).

@ddbaron
Copy link
Author

ddbaron commented May 11, 2016

@glena Thanks for the update and pointing out some possible issues.

I updated my versions to match yours:

  • Wordpress 4.5.2 (shared hosting on godaddy)
  • Wordpress Auth0 Integration 2.1.11
  • Wordpress JWT Authentication 1.1.1
  • WP REST API 2.0-beta13

Special note for wordpress on godaddy hosting: I had to modify the .htaccess to prevent the removal of the Authorization header:

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
RewriteBase /
RewriteRule ^index\.php$ - [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
</IfModule> 

The following use cases work, but only for users who exist in auth0 and have also used auth0 to login directly to WP at least once:

  1. GET /wp/v2/users/me
  2. GET /wp/v2/users/1 ( a known ID in the WP user database)
  3. POST /wp/v2/posts (works as expected: for users with roles of authors and admins, does not work for subscribers)
  4. POST /wp/v2/comments (same)

For users who are registered in auth0, but who have not (and will not) login directly to WP, I receive the following text (but no exception is thrown). I'm not a php guy, so I hope you can decipher what's going on:

<b>Catchable fatal error</b>: Argument 1 passed to WP_Auth0_UserCreator::__construct() must be an instance of WP_Auth0_Options, none given, called in /home/content/p3pnexwpnas04_data02/76/2368376/html/wp-content/plugins/auth0/lib/WP_Auth0_UsersRepo.php on line 37 and defined in <b>/home/content/p3pnexwpnas04_data02/76/2368376/html/wp-content/plugins/auth0/lib/WP_Auth0_UserCreator.php</b> on line <b>8</b><br />

@glena
Copy link
Contributor

glena commented May 11, 2016

It should create the user if it does no exists, but seems I mess it up :D

It will be fixed in the next release, but in the meantime, can you change this line https://github.com/auth0/wp-auth0/blob/master/lib/WP_Auth0_UsersRepo.php#L37

for this:

$creator = new WP_Auth0_UserCreator($this->a0_options);

@glena
Copy link
Contributor

glena commented May 12, 2016

@ddbaron 2.2.1 should fix this

@ddbaron
Copy link
Author

ddbaron commented May 12, 2016

@glena I've done some cursory testing with 2.2.1 and it appears to be working well. Thank you for the fix!

@moneal
Copy link
Contributor

moneal commented May 12, 2016

I'm still getting a 401 response when requesting wp-json/wp/v2/users/me with a authorized request. I have some time today so I'll see if I can get some more details.

Using Login by Auth0 2.2.1 and Wordpress JWT Authentication 1.1.1 on WP 4.5.2

@glena
Copy link
Contributor

glena commented May 12, 2016

@moneal mmm weird. I will debug what is the api doing in this case, it should return the user info. I will try to make me time for this.

@moneal
Copy link
Contributor

moneal commented May 12, 2016

@glena I think I have it working, users/me is now redirecting to the correct user. It looks like my host, WP Engine needed the same .htaccess change that @ddbaron posted. I also needed to change the getAuthorizationHeader method to look for the header in lower case.

Here is my change:

protected static function getAuthorizationHeader() {
        $authorization = false;

        if (function_exists('getallheaders'))
        {
            $headers = getallheaders();
            if (isset($headers['Authorization'])) {
                $authorization = $headers['Authorization'];
            }
            if ( ! $authorization && isset($headers['authorization'])) {
                $authorization = $headers['authorization'];
            }
        }
        elseif (isset($_SERVER["Authorization"])){
            $authorization = $_SERVER["Authorization"];
        }

        return $authorization;
    }

@ddbaron
Copy link
Author

ddbaron commented May 12, 2016

@moneal I was having a similar issue with the /users/me endpoint, and I forgot to mention this earlier. Per this doc http://v2.wp-api.org/guide/problems/ that endpoint issues a redirect to the client. A redirect can cause the same authentication headers to be sent, but with different request data, causing the signature to fail.

A workaround is to Envelope the request using /users/me?_envelope.

NOTE: The request is enveloped so I had to pick out the 'data' element with the user info. Hope this helps.

@glena
Copy link
Contributor

glena commented May 12, 2016

I am thinking on allowing the access_token to be sent in the query string or request body (maybe configurable in the plugin settings) to get rid of the apache issue with the authorization header.

About this issue with /users/me, it sounds really weird. Why does it redirects the request?

@moneal
Copy link
Contributor

moneal commented May 12, 2016

The redirect thing has been talked about a lot from the REST team and I don't think they are going to change it. The ?_envelope parameter that @ddbaron posted works great. I actually just added that to my ionic app right before getting the notification :)

/users/me redirect info WP-API/WP-API#1365 and WP-API/WP-API#1093

@akhanukov
Copy link

Hi @glena and @moneal, just wondering if based on the recent release of WordPress 4.7 with the Rest API in the core, no support for the Basic Auth plugin, and with the only options for authentication into the Rest API being suggested as cookies or OAuth 1.0, has the need for this plugin to support Rest API v2 been elevated or scheduled? Or is this considered a working feature and any issues related to the htaccess or other issues people mentioned above?

If not, would you encourage the functionality be built into this plugin as a contribution? Thanks!

@glena
Copy link
Contributor

glena commented Dec 19, 2016

Didnt have time to take a look to the WordPress 4.7 Rest API, but it worth the effort to support it if it is posible.

About Rest API v2, the plugins works well with Rest API v2, there are some weird issues but the guys worked it out.

Anyway, PRs are always welcome :D

@akhanukov
Copy link

@glena Thanks! OK, just wanted to understand where this stood. I may just be missing something in my implementation. Are you aware of any example code for making an API call via the node.js client library? Such as:

var wp = new WPAPI({ endpoint: 'http://www.mysite.com/wp-json', // This assumes you are using basic auth, as described further below //username: 'username', //password: 'password', headers: { authorization: 'Bearer 27y27yf3r7fywr87yfrw87yf7wyf87wyfwr78fy8wr7rfyw78fyw78yf7wrfyr78fy87wrfy8rw7fyw8r7f' } }); wp.posts().create({ // "title" and "content" are the only required properties title: 'Your Post Title', content: 'Your post content', // Post will be created as a draft by default if a specific "status" // is not specified status: 'publish' }).then(function( response ) { // "response" will hold all properties of your newly-created post, // including the unique id the post was assigned on creation console.log( 'Y\\Post created.' ); console.log( response.id ); })

@akhanukov
Copy link

Hi @glena, Happy New Year! I was wondering if you had a chance to look at WordPress 4.7? Also, I'm wondering if you know of any example implementations or code snippets working with https://github.com/WP-API/node-wpapi/? Does anything look strange with my code above? Thanks!

@akhanukov
Copy link

I think I figured out my issue but I'm not sure how to resolve it. I'm using passwordless authentication to generate an id_token, but there's no way for the plugin to match User Property "email" to JWT Attribute "sub". Is there? Thanks!

@glena
Copy link
Contributor

glena commented Jan 9, 2017

Hi @akhanukov sorry for the delay. The only way to do that is programatically using the wp_jwt_auth_get_user filter. it is documented here https://github.com/auth0/wp-jwt-auth#overriding-the-user-repository-logic

@akhanukov
Copy link

Yup @glena, I think I came to the same conclusion this afternoon and am working on that now. Thanks!

@akhanukov
Copy link

Hi @glena, since I have tried a couple of things and nothing has worked so far, can you please provide any more instruction? Do I need to copy the filter and function within the class into my theme's function.php file? Or simply call it via a filter, in which case, I tried both the one from the page you link to as well as on the WordPress plugin page and both give me errors. Pardon my ignorance but if you could guide me a little further, I'm almost got this month long challenge squared away, :) Thanks!

@glena
Copy link
Contributor

glena commented Jan 10, 2017

First, did you try to ask for the mail scope when you authenticate the user? this way auth0 will add the email as a token claim and there is no need to parse the sub (which will be something like email|[email protected]).

Also, in the plugin configuration you can configure the User Property and the JWT Attribute that the plugin will use to look for the correct user (in the case of the sub it might not work since it can not match email==sub because of the id format). In this case if you ask for openid email scope in lock, you should use the email attribute of the JWT in the configuration.

BTW, you should NOT parse the id_token since the format might change, that is an internal auth0 id and can change if we need to.

Anyway, to do it programatically, in your functions.php add this:

add_filter( 'wp_jwt_auth_get_user', 'get_jwt_user', 10);
function get_jwt_user($jwt) {
        global $wpdb;
        if ($jwt instanceof WP_User) return $jwt;

// didnt test this line, take a look (BTW you shouldnt do that)
        list($provider, $email) = explode('|',$jwt->sub);

        $sql = 'SELECT u.*
                FROM ' . $wpdb->users . '
                WHERE email = %s';
        $userRow = $wpdb->get_row($wpdb->prepare($sql, $email));

        if (is_null($userRow)) {
            return null;
        }elseif($userRow instanceof WP_Error ) {
            self::insertAuth0Error('findAuth0User',$userRow);
            return null;
        }
        $user = new WP_User();
        $user->init($userRow);
        return $user;
}

finally, please dont mix stuff, this particular thing has nothing to do with the original issue (it is hard to follow up for other people looking for similar issues)

@akhanukov
Copy link

@glena Thank you for your assistance. Yes, sorry about posting this here. Originally I thought I had the same issues as the users above. We can move it to another thread if you like or hopefully this or the next comment should solve it.

I spent several hours after posting trying to implement this and while I called my function a little different, I was able to debug much of it via Postman. Yes, the place I left off was trying to get the email attribute into my jwt, figuring the ID was probably encoded or hashed. I've followed several tutorials or suggestions including https://auth0.com/docs/libraries/lock/v10/customization#connectionscopes-object-.

However since my login process uses Passwordless authentication (though I do also use the main Auth0 WordPress and Lock for the WP front end), the only place I figured I could request that scope is via the Auth0 Plugin > Advanced Settings Tab > Extra Settings tab, or via a rule (cursory trial and failure so far). Is this correct, because this didn't add it to the jwt id_token?

screen shot 2017-01-10 at 11 23 49 am

And since that tutorial references Lock 10, I have tried to toggle between Lock 9 (default in the plugin) and Use Lock 10, and when my id_token is generated, I still only see the 5 default attributes in the jwt.io Debugger.

Which brings me to my authentication API code. I have been using the auth0-node package (https://github.com/auth0/node-auth0/) for which I want to submit a PR to address auth0/node-auth0#148, as I have manually added the verifyEmailCode function in the past and since the last update that the other user is upset about. Unless you suggest I use another package? There's just so many! :)

As of 3am last night, I had added scope as an argument, but that also failed to generate an additional attribute.

var scope = 'openid profile email'; //submit the passcode to authenticate auth0.verifyEmailCode({ email: email, code: code, scope: scope }, function(err, profile, id_token, access_token) {

At this point, my guess is that the auth0-node package function doesn't have the extra argument I'm trying to pass for scope, but I am just starting to debug again. Please let me know your thoughts, I know I'm one tweak from success. :) And please feel free to move this to another or new thread. I'm look forward to blogging about how well this all works together, so thanks for your help!!

@glena
Copy link
Contributor

glena commented Jan 10, 2017

Lets follow up in #5

@glena glena closed this as completed Jan 10, 2017
aaguiarz added a commit that referenced this issue Nov 28, 2017
Update from Auth0 branch
@luisgagocasas
Copy link

resolved with:

RewriteCond %{HTTP:Authorization} ^(.)
RewriteRule .
- [e=HTTP_AUTHORIZATION:%1]

in .htaccess

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants