Obtain Request Token
Before the application can request authorization from the user, it must first
obtain a request token. The request token identifies the authorization
request. If the user grants access, the application can exchange this request
token for an access token. To obtain a request token, the application makes a
request to the service providers's request token URL (/oauth/request_token
,
in the case of Twitter):
POST /oauth/request_token
Host: api.twitter.com
Authorization: OAuth oauth_callback="https%3A%2F%2Fwww.example.com%2Foauth%2Fcallback%2Ftwitter",
oauth_consumer_key="cChZNFj6T5R0TigYB9yd1w",
oauth_nonce="ea9ec8429b68d6b77cd5600adbbb0456",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1318467427",
oauth_version="1.0",
oauth_signature="qCMIWvfCvmP0ZsfWGTPnuaPXsQE%3D"
The parameters for this request are conveyed in the Authorization
header.
Let's examine them.
oauth_callback
: URL to which the service provider will redirect the user after completing interaction with the user.oauth_consumer_key
: Identifies the application to the service provider. This is assigned when registering the application with Twitter.oauth_nonce
: A random string uniquely generated by Passport for each request, used to help prevent replay attacks.oauth_signature_method
: The signature method used to sign the request.oauth_timestamp
: The number of seconds since January 1, 1970 00:00:00 GMT.oauth_version
: The version of OAuth used to authorize the request, set to "1.0".oauth_signature
: A cryptographic signature used to authenticate the request. Passport computes this automatically using the application's consumer secret.
When Twitter receives this request, it authenticates the application by verifying that the signature was produced by the corresponding consumer key and secret. If successful, Twitter generates a request token and secret:
200 OK
Content-Type: application/x-www-form-urlencoded
oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&
oauth_token_secret=veNRnAWe6inFuo8o2u8SLLZLjolYDmDP7SzL0YfYI&
oauth_callback_confirmed=true
Let's examine the parameters in this response.
oauth_token
: A unauthorized request token. The user will be requested to authorize this token. If granted, the request token can be exchanged for an access token.oauth_token_secret
: A shared secret used to cryptographically demonstrate ownership of the request token when exchanging it for an access token.oauth_callback_confirmed
: A flag set totrue
to indicate that the service provider received the application's callback URL in theoauth_callback
parameter. This indicates that the service provider supports OAuth 1.0a, which addresses a session fixation vulnerability in OAuth 1.0.
Now that the application has obtained a request token, it is ready to request authorization from the user. First, Passport stores the token secret so that it can be later loaded when obtaining an access token. Then, the user's web browser is redirected to Twitter:
302 Found
Location: https://api.twitter.com/oauth/authenticate?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0
The web browser follows this redirect and makes a request to Twitter:
GET /oauth/authenticate?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0
Host: api.twitter.com
This request is sent to the service providers's user authorization URL
(/oauth/authenticate
, in the case of Twitter). Let's examine the parameters
in this request.
oauth_token
: The unauthorized request token obtained in the previous step, which the user is being requested to authorize.
At this point, Twitter will interact with the user. This interaction will typically involve logging the user in (if they are not already logged in) and obtaining their consent (if it has not been previously obtained). Once that has been completed, Twitter redirects the user back to the application:
302 Found
Location: https://www.example.com/oauth/callback/twitter?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&oauth_verifier=uw7NjWHT6OJ1MpJOXsHfNxoAhPKpgI8BlYDhxEjIBY
The web browser follows this redirect and makes a request to the application:
GET /oauth/callback/twitter?oauth_token=NPcudxy0yU5T3tBzho7iCotZ3cnetKwcTIRlX0iwRl0&oauth_verifier=uw7NjWHT6OJ1MpJOXsHfNxoAhPKpgI8BlYDhxEjIBY
Host: www.example.com
This request is sent to the application's callback URL (/oauth/callback/twitter
,
in this case), which corresponds to the value of the oauth_callback
parameter in
the earlier request. Let's examine the parameters in this request.
oauth_token
: The request token, which the user has now either authorized or denied.oauth_verifier
: The verification code required to exchange the request token for an access token.
This request is handled by a route in the application:
router.get('/oauth/callback/twitter', passport.authenticate('twitter', {
successReturnToOrRedirect: '/',
failureRedirect: '/login'
}));
This route invokes Passport, and in particular the passport-oauth1
strategy. The strategy first loads the previously stored secret associated with
the request token. It then exchanges the request token for an access token.