In this post, I try to describe what OAuth authentication is, how to do it, and why it is needed.
This is a translation of a post of mine originally written in Japanese, and based on and following the flow described in a documentation written by @rmccue, the author WP REST API – OAuth 1.0a Server plugin, and the API.
- OAuth1/Auth-Flow.md at master · WP-API/OAuth1 · GitHub
- Paw – The ultimate REST client for Mac: this is the app I’m using to build requests easily.
When you find something wrong, I’m happy to get feedbacks as comments or reply to @shinichiN on twitter.
Step 0. Getting Client Key and Client Secret from WordPress
We are using WP-API/OAuth1 · GitHub plugin to turn our WordPress into a OAuth provider. (And if your WordPress is 4.4.n, the WP REST API plugin needs to be activated, too.) This plugin offers a GUI to create client key and client secret under Users menu in admin panel.
Description is for human readability so you can put any name you want. In this post we don’t utilize the callback url so input http://example.com/auth/success or such.
You will see
Client Key and
Client Secret which we use in the authentication flow.
These credentials can be generated with wp-cli commands, too:
$ wp oath1 add.
Summary of OAuth flow and why this is useful
The key to understanding how OAuth works is understanding the authorization flow. This is the process clients go through to link to a site.
And the flow is:
1. Temporary Credentials Acquisition
The client gets a set of temporary credentials from the server.
To get these credentials, we use the client key / secret we just got from the WordPress admin panel. These temporary credentials are called Request Token.
The user “authorizes” the request token to access their account.
This is when a logged in human user will authorize an application to work on behalf of them.
3. Token Exchange
The client exchanges the short-lived temporary credentials for a long-lived token.
In other words, client application exchanges their Request Token for a Access Token. Access token is the token which the client application will use to get protected data, creating, updating deleting data in WordPress through the WP REST API.
Why OAuth ?
Assuming that there is a WordPress site which is WP REST API activated, and what we want to do is to perform something only logged-in users can, with third-party applications.
We want to get post meta data which is not public to non-authorized request. We want to add posts, update taxonomy terms, delete users from iPhone apps, desktop apps and web apps, through WP REST API.
The first idea we come up with might be “Let’s send our login name / password and let the WordPress know that the client application is me!” but this is really bad in several ways.
- Sending user name and password through network is bad.
- Giving your ID and password is bad, especially the app is a third-party owned by someone else.
To avoid these problems is the reason we need OAuth. Through the 3 steps flow of authentication, the communication is happening among a WordPress site, a third-party application, and a logged in user. In step 2, a human user will be logged in to the website, in this case our WordPress, and authorize the third party app. After the authorization, application will be able to perform what the user allows.
To enable this, giving an app the right to do things without giving the password, is the purpose of OAuth.
Three endpoint URLs to communicate
We now know that there will be 3 steps in our process and there are 3 endpoint urls that correspond to each steps.
These 3 endpoints are offered by the WP OAuth plugin and are shown when we access
/wp-json on your WordPress.
$.authentication.oauth1.request: the endpoint to retrieve a request token and secret.
$.authentication.oauth1.authorize: the endpoint a user will authorize the app.
$.authentication.oauth1.access: the endpoint where the app will get the access token.
In the 3 steps, we are going to send 3 requests to these endpoints.
Step 1: Temporary Credentials Acquisition
The first step is acquiring the temporary credentials, which is also called request token and the endpoint url is
Toward this endpoint, we send a signature created of a few things, including the
client key / secret we got from the WordPress admin UI.
The image below is how I input my key and secret into the Paw UI.
Paw shows us what the actual request sent to the server was and it was like this.
GET /oauth1/request HTTP/1.1 Authorization: OAuth oauth_consumer_key="fbQ9KPUmdDLP", oauth_nonce="4Lxk40ujU5KQU7j53E06dKGlLwQkKm1W", oauth_signature="Ra%2BrRiy2tLKk9ub0qMABW4g57gQ%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1451907555", oauth_version="1.0" Host: wp-api.dev Connection: close User-Agent: Paw/2.2.7 (Macintosh; OS X/10.9.5) GCDHTTPRequest
At the line 2, we can see the Authorization header which includes several
key=value strings, separated by commas and spaces. Let’s see what they are.
Client Keywe got from WordPress.
oauth_nonceis a random string created automatically by Paw. nonce stands for number used once and is used to prevent the OAuth provider performing a procedure more than once if the same request is sent.
oauth_timestampis also generated by Paw. This is used by the server to control how long it needs to hold the nonce and tokens. What’s the point of a timestamp in OAuth if a Nonce can only be used one time? – Stack Overflow might be good if interested.
oauth_signatureis also generated by Paw and this is the main part of this request. How Paw generates it ( and how we should do it with our program when creating an app ) can be described as below. For further reading, please go to the github repository of the plugin, OAuth1/Signing.md.
- combine client key, timestamp, nonce into a string in a predefined manner.
- create another string with
- Hash the 2 strings with
Note that the client secret it self is not sent to the server. It is only used in the generating process of the hashed
oauth_signature. Once the request is sent, our WordPress site will check them by doing the same thing as the client has done. WordPress knows the client secret, because WP is the provider of it, and so can tell if the request is sent by a valid app.
When the check is done, WordPress will respond sending back
oauth_token_secret and these are the temporary credentials, the request tokens.
Here is the response.
HTTP/1.1 200 OK Date: Mon, 04 Jan 2016 10:00:56 GMT Server: Apache X-Powered-By: PHP/7.0.0 Content-Length: 134 Connection: close Content-Type: application/x-www-form-urlencoded; charset=utf-8 oauth_token=CZpmXOtP98rsvrBk668QZZxE&oauth_token_secret=CTAdf4c1ZdLzoJJvC195VoMN3t9t3oPphK3sAbSceHYfUjwl&oauth_callback_confirmed=true
Step 2: Authorize
Now we are going to use the oauth_token with the second endpoint url,
/oauth1/authorize/. In this step, a human logging-in is required and WordPress does several redirections so we use a browser. Access
http://example.com/oauth1/authorize?oauth_token=<the oauth_token we got in the step 1> with your browser.
Accessed, you will be redirected to the authorization screen, or the WordPress login form if not yet logged in.
Here, a human user will give the authority, capability to access and change the data inside WordPress. Note that the oauth_token parameter is known only to the user who’s passed the step 1, where can be passed only by the one with the client key /secret.
If we click the “Authorize” link, WordPress will mark the token as valid and will return us a
oauth_verifier, a string to prevent CSRF. We use it in the next step.
Step 3: Token Exchange
In this final step, we are getting the access token. The endpoint url is
/oauth1/access/ and we are going to send a POST request with another signature and verification token we got in the step 2.
WordPress will check the signature and if confirmed, will give us a new pair of
oauth_token_secret, which we call access token. After exchanging the tokens, we can discard the old
oauth_verifier because we don’t need them anymore.
Building a request in Paw is a bit tricky. We need to add
oauth_verifier="<oauth_verifier we got in the step 2>" in the Additional Params field.
The request looked like this.
POST /oauth1/access/ HTTP/1.1 Authorization: OAuth oauth_consumer_key="fbQ9KPUmdDLP", oauth_nonce="cEsC2kNG16ETXhjmjCb4wOe0otwH6fhN", oauth_signature="KgLDxSAYSbkGh1htQwPPZ8PMoKw%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1451915663", oauth_token="CZpmXOtP98rsvrBk668QZZxE", oauth_version="1.0", oauth_verifier="Etrc3Asa5EYRikFxUN6WMzJT" Host: wp-api.dev Connection: close User-Agent: Paw/2.2.7 (Macintosh; OS X/10.9.5) GCDHTTPRequest Content-Length: 0
This time again Paw’s generated a signature using
- client key / secret
- oauth_token / secret ( the old request token )
- nonce, verifier, timestamp
- the HMAC-SHA1 method
The secrets are not sent. It’s impossible to get the same signature without knowing the secret and so WordPress can know that the client has the secrets, and so is safe and authorized.
When the check is done, WordPress will give us the access tokens. They have the same key names, oauth_token and oauth_token_secret. We just delete the request tokens away and switch them with the new ones.
Now, the application is authorized and linked to the website.
Send request to the WP REST API with OAuth access token
Let’s send to the API a request, which is allowed only to authenticated apps. Here we try getting post meta data.
oauth_token_secret in the Paw to new ones and GET request to
The request looks like this and we can see that the signature created with the same method is sent.
GET /wp-json/wp/v2/posts/1/meta HTTP/1.1 Authorization: OAuth oauth_consumer_key="fbQ9KPUmdDLP", oauth_nonce="UqeSQCG8m1C4Px5QMcH2Je5OhEc6OQr7", oauth_signature="ZfwTyXEm3UE6CQJ5E52D82QNU%2B0%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1451916352", oauth_token="PdJ2r3GHkbKlwQNKb5OZoZRE", oauth_version="1.0" Host: wp-api.dev Connection: close User-Agent: Paw/2.2.7 (Macintosh; OS X/10.9.5) GCDHTTPRequest