User:Chlod/OAuth

OAuth/For Developers is a little too summarized for anyone who wants an in-depth explanation of how OAuth works in the context of MediaWiki. This document attempts to break it down and explain most details without being too complicated.

Glossary
This is a short glossary of terms for newer developers. Note that some of the explanations here are massively oversimplified. Cryptography is a very complex field, so some level of simplification is required to make concepts easier to understand.


 * Consumer refers to any application which uses information using OAuth.
 * Nice URL refers to a formatted URL, such as https://en.wikipedia.org/wiki/Main_Page.
 * Non-nice URL refers to an unformatted URL, such as https://en.wikipedia.org/w/index.php?title=Main_Page.
 * RSA refers to Rivest–Shamir–Adleman encryption, a method of encryption which requires the use of a public key (one that can be shared with anyone and can only encrypt data) and a private key (one that you must keep secret and can be used to both encrypt and decrypt data).
 * HMAC refers to hash-based message authentication code, a method of cryptography which relies on a pre-shared secret instead of keys. This (or RSA) is used to ensure that the OAuth authorization request came from your application itself.

OAuth 1.0a
OAuth 1.0a requires you to provide OAuth information using the Authorization HTTP header. As a reference, we're going to use the English Wikipedia API for OAuth authorization. We'll assume that we're working with a non-owner-only application with no provided public RSA key on consumer registration.

Three-legged OAuth
Three-legged OAuth is used whenever creating a non-owner-only application. It's called "three-legged" since it consists of three steps.

Step 1: Initiate
To initiate authorization, make a GET request to Special:OAuth/initiate using the non-nice URL (for example, https://en.wikipedia.org/w/index.php?title=Special:OAuth/initiate) with an OAuth authorization header. You should use an OAuth library to do these steps automatically, but a low-level representation is provided below for those who prefer to work with plain JavaScript or curl.

JavaScript
You can use the oauth-1.0a npm package for automatically signing your OAuth requests. This eases the process of making signed requests.

Low-level
The OAuth authorization header looks like the following: OAuth oauth_consumer_key="XXXXX",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1640138239",oauth_nonce="44938yXv2GT",oauth_callback="oob",oauth_signature="..." It consists of the following parts:


 * – a mandatory string at the start of the header, indicating that this is an OAuth authorization header.
 * – your application's consumer key. This is shown only once when registering your application on Special:OAuthConsumerRegistration/propose.
 * – indicates the signature method used to generate the OAuth signature (provided in a later field). Since we set the application up without providing a public RSA key, this will be set to, the automatic method selected.
 * – the current UNIX timestamp as of the time the message was made and signed.
 * – a randomly-generated string of characters which prevent you from accidentally re-initiating an OAuth authorization (such as when a user retries a failed web request). You should always change this whenever making a new request!
 * – the callback URL to send the user to after authorization. If during consumer registration, this was set to a constant URL (and not as a prefix), the value must be set to "oob". Otherwise, it should be set to the callback URL you wish to send the user to after authorizing.
 * – an HMAC-SHA1 hash of all signed values. We'll get into that below.

The HMAC-SHA1 hash is a hashed representation of a string called the "signature base string". This string contains information about the request you're making and the OAuth consumer information as well. If your hash does not compute properly (possibly due to an incorrectly-computed hash), your authorization request will not begin.

The signature base string is made with the HTTP request type, the HTTP URL, and the "parameter string". The parameter string is a string which contains all values to be signed, including query parameters and all OAuth fields. The following JavaScript function generates a parameter string. After creating the parameter string, you can then create the signature base string by combining the HTTP method, the (percent-encoded) URL, and the percent-encode parameter string. When you're done, the signature base string should look like this: GET&https%3A%2F%2Fen.wikipedia.org%2Fw%2Findex.php%3Ftitle%3DSpecial%3AOAuth%2Finitiate&oauth_consumer_key%3DXXXXX%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1640138239%26oauth_nonce%3D44938yXv2GT%26oauth_callback%3Doob and if your consumer key was, the HMAC-SHA1 signature should be.

Step 2: Authorize
Step 1 should have given you a request token and secret in the  and   fields, respectively. From here, you need to redirect the user to a Special:OAuth/authorize, with the  query parameter set as your consumer key and   set as the token provided in the previous request. The user should see a confirmation dialog showing them what data is being requested and some basic information about the app.

If they choose not to give access, they are informed by Special:OAuth. If they gave access, you can proceed to Step 3.

Step 3: Getting the token
The user will be redirect to the callback URL provided with an  query parameter. You now need to sign another request, this time to https://en.wikipedia.org/w/index.php?title=Special:OAuth/token, with the request token and request secret set as your OAuth access token and token secret, and the  parameter.

MediaWiki will respond with the new access token and secret that you need for whatever requests you'll be making next, such as those with the Action API. All of those requests must be signed much like how Step 3 signs the request to get the OAuth token.

JavaScript
This picks up from the code used in Step 1.

OAuth 2.0
OAuth 2.0 is the preferred method of employing OAuth with a MediaWiki instance, as it requires less steps and simplifies the flow for developers. OAuth 2 tokens, however, have a very short expiry time and need to be refreshed with a "refresh token" when they expire. This, however, gets rid of the need to reauthorize every once-in-a-while for users.