Skip to content

Commit cd82410

Browse files
committed
Add Gitbook guide
1 parent 34e6b6f commit cd82410

File tree

15 files changed

+373
-43
lines changed

15 files changed

+373
-43
lines changed

README.md

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,26 @@
1-
# OAuth 1.0a Server for WordPress
2-
This project is an OAuth 1.0a-compatible authentication method for WordPress.
3-
This is a separate-but-related project to [WP API][], designed to provide
4-
authentication suitable for the API.
1+
# WP REST API - OAuth 1.0a Server
52

6-
## Documentation
3+
Connect applications to your WordPress site without ever giving away your password.
74

8-
Read the [plugin's documentation][docs].
5+
This plugin uses the OAuth 1.0a protocol to allow delegated authorization; that is, to allow applications to access a site using a set of secondary credentials. This allows server administrators to control which applications can access the site, as well as allowing users to control which applications have access to their data.
96

10-
[docs]: https://github.com/WP-API/OAuth1/tree/master/docs
7+
## New to OAuth
118

9+
We strongly recommend you use an existing OAuth library. You'll be best off if you understand the authorization process, but leave the actual implementation to well-tested libraries, as there are a lot of edge cases.
1210

13-
## Quick Setup
11+
Start reading from [the Introduction](docs/introduction/README.md) to get started!
1412

15-
Want to test out the OAuth API and work on it? Here's how you can set up your own
16-
testing environment in a few easy steps:
13+
## For OAuth Veterans
1714

18-
1. Install [Vagrant](http://vagrantup.com/) and [VirtualBox](https://www.virtualbox.org/).
19-
2. Clone [Chassis](https://github.com/Chassis/Chassis):
15+
If you already know how to use OAuth, here's the lowdown:
2016

21-
```bash
22-
git clone --recursive [email protected]:Chassis/Chassis.git api-tester
23-
```
24-
25-
3. Grab a copy of WP API and OAuth API:
26-
27-
```bash
28-
cd api-tester
29-
mkdir -p content/plugins content/themes
30-
cp -r wp/wp-content/themes/* content/themes
31-
git clone --recursive [email protected]:WP-API/WP-API.git content/plugins/json-rest-api
32-
git clone [email protected]:WP-API/OAuth1.git content/plugins/oauth-server
33-
```
34-
35-
4. Start the virtual machine:
36-
37-
```bash
38-
vagrant up
39-
```
40-
41-
5. Browse to http://vagrant.local/wp/wp-admin/ and activate the WP API and OAuth
42-
API plugins
43-
44-
```
45-
Username: admin
46-
Password: password
47-
```
48-
49-
6. Refer to the [documentation][docs] on how to connect an OAuth client.
50-
51-
[WP API]: https://github.com/WP-API/WP-API
17+
* The plugin uses **OAuth 1.0a** in
18+
* We use the **three-legged flow**
19+
* To find the REST API index, apply the [API autodiscovery process](http://v2.wp-api.org/guide/discovery/)
20+
* The endpoints for the OAuth process are available in the REST API index: check for `$.authentication.oauth1` in the index data.
21+
* The **temporary credentials** (request token) endpoint is `$.authentication.oauth1.request` (typically `/oauth1/request`)
22+
* The **authorization** endpoint is `$.authentication.oauth1.authorize` (typically `/oauth1/authorize`)
23+
* The **token exchange** (access token) endpoint is `$.authentication.oauth1.access` (typically `/oauth1/access`)
24+
* Your callback URL must match the registered callback URL for the application in the scheme, authority (user/password) host, port, and path sections. (**Subpaths are not allowed.**)
25+
* The only signature method supported is **HMAC-SHA1**.
26+
* OAuth parameters are supported in the Authorization header, query (GET) parameters, or request body (POST) parameters (if encoded as `application/x-www-form-urlencoded`). **OAuth parameters are not supported in JSON data.**

book.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"gitbook": "2.4.3",
3+
"structure": {
4+
"summary": "docs/README.md"
5+
},
6+
"plugins": ["edit-link", "prism", "-highlight", "github"],
7+
"pluginsConfig": {
8+
"edit-link": {
9+
"base": "https://github.com/WP-API/OAuth1/tree/master",
10+
"label": "Edit This Page"
11+
},
12+
"github": {
13+
"url": "https://github.com/WP-API/OAuth1/"
14+
}
15+
}
16+
}

docs/.gitignore

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Node rules:
2+
## Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
3+
.grunt
4+
5+
## Dependency directory
6+
## Commenting this out is preferred by some people, see
7+
## https://docs.npmjs.com/misc/faq#should-i-check-my-node_modules-folder-into-git
8+
node_modules
9+
10+
# Book build output
11+
_book
12+
13+
# eBook build output
14+
*.epub
15+
*.mobi
16+
*.pdf

docs/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Table of Contents
2+
3+
* [Start Here](/README.md)
4+
* [Introduction](/docs/introduction/README.md)
5+
* [Why OAuth?](/docs/introduction/OAuth.md)
6+
* [Why OAuth 1.0a?](/docs/introduction/OAuth-1.md)
7+
* [Setup](/docs/introduction/Setup.md)
8+
* [Basics](/docs/basics/README.md)
9+
* [Registering an Application](/docs/basics/Registering.md)
10+
* [The Authorization Flow](/docs/basics/Auth-Flow.md)
11+
* [Signing Requests](/docs/basics/Signing.md)
12+
* [Advanced](/docs/advanced/README.md)
13+
* [Desktop/Mobile Clients](/docs/advanced/Desktop.md)
14+
* [Web Clients](/docs/advanced/Web.md)

docs/advanced/Desktop.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Desktop/Mobile Clients
2+
3+
OAuth was originally designed for web applications, so desktop and mobile clients may wish to use the OAuth flow slightly differently. The authorization flow for OAuth requires both a browser and a callback URL for the second leg.
4+
5+
6+
## Callback URL Schemes
7+
8+
The OAuth plugin supports any valid URL scheme, including custom schemes. This allows using custom schemes for callback URLs, which can then trigger your application. Note that for custom schemes, the authority (user and password) part must be empty, and the host **must not be empty** and must not contain invalid characters (such as `:#?[]`).
9+
10+
For example, the following URLs are **invalid**:
11+
* `custom-app://`
12+
* `custom-app://?oauth_callback`
13+
* `custom-app://user:pass@oauth_callback`
14+
15+
The following URLs are **valid**:
16+
* `custom-app://oauth_callback`
17+
* `custom-app://oauth?callback`
18+
* `custom-app://oauth/callback`
19+
* `custom-app://oauth_callback:42`
20+
21+
22+
## Out-of-Band Flow
23+
24+
For clients without the ability to handle a callback URL, an out-of-band flow can be used. Rather than redirecting the user after authorization, this flow displays the verifier token to the user to copy to the client.
25+
26+
To trigger the out-of-band flow, the callback URL must be set to `oob`. After the user has authorized the application, they'll be redirected to an internal page on the site which displays the verifier token. This can either be copy-and-pasted into the client (e.g. for command-line applications), or typed in manually.
27+
28+
With the callback URL set to `oob`, the supplied callback and registered callback must match exactly, and must be `oob`. This means that clients can either have a callback URL **or** out-of-band handling, and cannot work with both.
29+
30+
31+
## Best Practices
32+
33+
* Clients should use callback URLs if at all possible, with out-of-band flow as a last resort.
34+
* Clients should prefer the system browser rather a built-in browser, as the former typically has allows better usage of saved passwords. Using a built-in browser also gives a dangerous signal to users, as a compromised app could fake a login screen and phish their credentials.

docs/advanced/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Advanced
2+
3+
* [Desktop/Mobile Clients](Desktop.md)
4+
* [Web Clients](Web.md)

docs/advanced/Web.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Web Clients
2+
3+
OAuth was originally designed for working with web clients, so the process should be fairly smooth for most developers. There are some use cases that are tricky however, although not impossible to work with.
4+
5+
6+
## Distributed or Multi-Domain Clients
7+
8+
One issue for clients with multiple domains (such as multisite WordPress installs) is callbacks: clients can only have a single registered callback, with no variation in most of the URL. This can make working with multiple domains tricky.
9+
10+
This can be easily handled by adding extra query parameters to the callback URL, as these **can** be set on a per-request basis. These can then be handled by your callback URL to pass on to a secondary callback.
11+
12+
For example, for a WordPress multisite, set the callback URL to a URL on the main site. A `site={id}` parameter can then be added when setting the callback for the request. The callback can then redirect the user's browser to a per-site callback based on this parameter (ensuring to pass along the `oauth_token` and `oauth_verifier` parameters.)
13+
14+
**Note:** When using this method, be sure to verify the site. Check that the request token being handled was actually created by the site asking for it. If you're using domains instead of site IDs, be *very* careful not to redirect to an unknown domain. Failure to check this can easily lead to CSRF (phishing) attacks.
15+
16+
17+
## In-Browser Clients
18+
19+
Increasingly with modern JavaScript-based applications, the application may run entirely in the user's browser. OAuth 1 was (unfortunately) not designed for this use case. OAuth 2 goes a long way to correcting this, but as mentioned previously, [we can't use it :(](../introduction/OAuth-1.md)
20+
21+
This primarily falls down to the application secret. OAuth 1.0a relies on the client secret being secret (duh) as the basis for the authorization flow. This is core to the signature process. Without this being secret, other applications can issue their own tokens as your application. OAuth 2 makes allowances for clients with public secrets with the `implicit` flow.
22+
23+
The simplest way to handle this is to introduce a minimal server-side component. This can be created from scratch, or a prebuilt server such as [Guardian](http://guardianjs.com/) can be used instead.
24+
25+
26+
## Best Practices
27+
28+
* Never expose secrets, such as in JS client-side applications. Instead, use a proxy to handle the OAuth authentication.
29+
* Similarly, never expose the verifier to sites outside of your control. The verifier is specifically intended for CSRF mitigation, so be exceedingly careful before passing it on to another URL.

docs/basics/Auth-Flow.md

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# The Authorization Flow
2+
3+
The key to understanding how OAuth works is understanding the authorization flow. This is the process clients go through to link to a site.
4+
5+
The flow with the OAuth plugin is called the **three-legged flow**, thanks to the three primary steps involved:
6+
7+
* **Temporary Credentials Acquisition**: The client gets a set of temporary credentials from the server.
8+
* **Authorization**: The user "authorizes" the request token to access their account.
9+
* **Token Exchange**: The client exchanges the short-lived temporary credentials for a long-lived token.
10+
11+
## Temporary Credentials Acquisition
12+
13+
The first step to authorization is acquiring temporary credentials (also known as a **Request Token**). These credentials are short-lived (typically 24 hours), and are used purely for the initial authorization process. They don't grant any access to data on the server, and cannot be used for anything except the authorization flow.
14+
15+
These credentials are acquired by an initial HTTP request to the server. The client starts by sending a POST request to the temporary credential URL, typically `/oauth1/request` with the plugin. (This URL should be autodiscovered from the API, as individual sites may move this route, or delegate the process to another server.) This looks something like:
16+
17+
This request includes the client key (`oauth_consumer_key`), the authorization callback (`oauth_callback`), and the request signature (`oauth_signature` and `oauth_signature_method`). This looks something like:
18+
19+
```
20+
POST /oauth1/request HTTP/1.1
21+
Host: server.example.com
22+
Authorization: OAuth realm="Example",
23+
oauth_consumer_key="jd83jd92dhsh93js",
24+
oauth_signature_method="HMAC-SHA1",
25+
oauth_timestamp="123456789",
26+
oauth_nonce="7d8f3e4a",
27+
oauth_callback="http%3A%2F%2Fclient.example.com%2Fcb",
28+
oauth_signature="..."
29+
```
30+
31+
The server checks the key and signature to ensure the client is valid. It also checks the callback to ensure it's valid for the client.
32+
33+
Once the checks are complete, the server creates a new set of Temporary Credentials (`oauth_token` and `oauth_token_secret`) and returns them in the HTTP response (URL encoded). This looks something like:
34+
35+
```
36+
HTTP/1.1 200 OK
37+
Content-Type: application/x-www-form-urlencoded
38+
39+
oauth_token=hdk48Djdsa&oauth_token_secret=xyz4992k83j47x0b&oauth_callback_confirmed=true
40+
```
41+
42+
These credentials are then used as the `oauth_token` and `oauth_token_secret` parameters for the Authorization and Token Exchange steps.
43+
44+
(The `oauth_callback_confirmed=true` will always be returned, and indicates that the protocol is OAuth 1.0a.)
45+
46+
47+
## Authorization
48+
49+
The next step in the flow is the authorization process. This is a user-facing step, and the one that most users will be familiar with.
50+
51+
Using the authorization URL supplied by the site (typically `/oauth1/authorize`), the client appends the temporary credential key (`oauth_token` from above) to the URL as a query parameter (again as `oauth_token`). The client then directs the user to this URL. Typically, this is done via a redirect for in-browser clients, or opening a browser for native clients.
52+
53+
The user then logs in if they aren't already, and authorizes the client. They can also choose to cancel the authorization process if they don't want to link the client.
54+
55+
If the user authorizes the client, the site then marks the token as authorized, and redirects the user back to the callback URL. The callback URL includes two extra query parameters: `oauth_token` (the same temporary credential token) and `oauth_verifier`, a CSRF token that needs to be passed in the next step.
56+
57+
58+
## Token Exchange
59+
60+
The final step in authorization is to exchange the temporary credentials (request token) for long-lived credentials (also known as an **Access Token**). This request also destroys the temporary credentials.
61+
62+
The temporary credentials are converted to long-lived credentials by sending a POST request to the token request endpoint (typically `/oauth1/access`). This request must be signed by the temporary credentials, and must include the `oauth_verifier` token from the authorization step. The request looks something like:
63+
64+
```
65+
POST /oauth1/access HTTP/1.1
66+
Host: server.example.com
67+
Authorization: OAuth realm="Example",
68+
oauth_consumer_key="jd83jd92dhsh93js",
69+
oauth_token="hdk48Djdsa",
70+
oauth_signature_method="HMAC-SHA1",
71+
oauth_timestamp="123456789",
72+
oauth_nonce="7d8f3e4a",
73+
oauth_verifier="473f82d3",
74+
oauth_signature="..."
75+
```
76+
77+
The server again checks the key and signature, as well as also checking the verifier token to [avoid CSRF attacks](http://oauth.net/advisories/2009-1/).
78+
79+
Assuming these checks all pass, the server will respond with the final set of credentials in the HTTP response body (form data, URL-encoded):
80+
81+
```
82+
HTTP/1.1 200 OK
83+
Content-Type: application/x-www-form-urlencoded
84+
85+
oauth_token=j49ddk933skd9dks&oauth_token_secret=ll399dj47dskfjdk
86+
```
87+
88+
At this point, you can now discard the temporary credentials (as they are now useless), as well as the verifier token.
89+
90+
Congratulations, your client is now linked to the site!

docs/basics/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Basics
2+
3+
* [Registering an Application](Registering.md)
4+
* [The Authorization Flow](Auth-Flow.md)
5+
* [Signing Requests](Signing.md)

docs/basics/Registering.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Registering an Application
2+
3+
Before you can talk to the server, you need to establish your credentials on the site. This involves registering your application with the site.
4+
5+
Applications can only be registered by site administrators, and must be registered on each site individually. (We're working on making it possible in the future to register once with a central authority to make this process easier.)
6+
7+
To register an application, open your site dashboard and head to Users > Applications, then click Add New. You'll need to enter the name of the application, an optional description, and the callback URL. This callback URL is used during the authorization process to redirect users back to after connecting. This URL can be changed later if you don't have a callback endpoint yet.
8+
9+
## Callback URLs
10+
11+
The callback URL is used during the authorization process. After users authorize your application on the site, they'll be redirected back to your callback URL. This callback needs to save the verifier token passed in, which is used in the third leg of the flow. The callback also typically starts the third leg (token exchange) on the server side. (The next section, [the Authorization Flow](Auth-Flow.md), expands more on how the callback URL is used.)
12+
13+
At the start of the OAuth flow, you pass in your OAuth callback URL for the specific request, which allows you to customise the callback URL for each request as needed. The OAuth plugin requires that your supplied callback URL match the scheme, authority (user and password part), host, port, and path of the registered callback URL. Only the query parameters and fragment (hash part) may differ from your registered URL. (This differs from some OAuth implementations, which allow subpaths of the callback URL.)
14+
15+
For sites with multiple domains or subdomains (e.g. a WordPress multisite network), the recommended method for handling this is to have a singular "main" callback URL which redirects to the specific site. During the request process, the site ID can then be added to the callback URL as a query parameter.
16+
17+
[Non-web applications](../advanced/Desktop.md) may wish to use custom URL schemes, or out-of-band handling. Out-of-band handling is triggered by setting the callback URL to the string `oob`. Rather than redirect after authorization, the site will instead display the verifier code to the user, which they then copy-and-paste or otherwise provide to the application.

0 commit comments

Comments
 (0)