How to create OAuth 1.0a signature in Node.js?

Soni Pandey
5 min readApr 16, 2020

In this article, we’ll learn about how to create oauth_signature without token and how our authorization header should look like. Recently I found some challenges to achieve this in Node.js (Javascript). So, writing this article to make it easier for others based on my experience.

What is OAuth?
OAuth is an open-standard authorization protocol or framework that provides applications the ability for “secure designated access”. OAuth doesn’t share password data but instead uses authorization tokens to prove an identity between consumers and service providers. OAuth is an authentication protocol that allows you to approve one application interacting with another on your behalf without giving away your password.

OAuth doesn’t have a single set of credentials. Instead, it splits the concept of credentials into two: client credentials, and user tokens. Clients register with sites they want to access, but this doesn’t give them any inherent access. Users then authorize the client to perform actions on their behalf.

Authorization Header — OAuth 1.0a uses the Authorization header as a way to authenticate the client to the OAuth Provider itself. OAuth versions (1.0a, 2.0)use the Authorization header when sending API requests to the Resource Server.

Authorization token look like -

Authorization: OAuth
oauth_consumer_key="key",
oauth_token="token",
oauth_signature_method="HMAC-SHA1",
oauth_timestamp="123456789",
oauth_nonce="nonce",
oauth_signature="...",
oauth_version="1.0"

oauth_consumer_key — The client identifier.
oauth_token (optional) — The temporary credentials identifier, if applicable.
oauth_signature_method — The signature method. For valid values, see OAuth Signature Method (1.0a) values.
oauth_timestamp — The timestamp value. Must be a positive integer. The timestamp is expressed in the number of seconds.
oauth_nonce — The random nonce value. The nonce value must be unique across all requests with the same timestamp, client credentials, and token combinations.
oauth_signature — The signature base string: a consistent, reproducible concatenation of several of the HTTP request elements into a single string.
oauth_version (optional)— An optional parameter which, if present, must be set to 1.0.

Creating an oauth_signature

The request used to demonstrate signing is a GET to = https://schoolwebsite.org/campus/oneroster/schoolName/learningdata/v1/schools?offset=0&limit=100&filter=status='active'.

Collecting the request method and URL -

To produce a signature, start by determining the HTTP method and URL of the request. These two are known when creating the request, so they are easy to obtain.

The request method will almost always be GET or POST for Twitter API requests.

HTTP Method — GET

The base URL is the URL to which the request is directed, minus any query string or hash parameters. It is important to use the correct protocol here, so make sure that the “https://” portion of the URL matches the actual request sent to the API.

Base URL — https://schoolwebsite.org/campus/oneroster/schoolName/learningdata/v1/schools

Collecting parameters —

Next, gather all of the parameters included in the request. There are two such locations for these additional parameters — the URL (as part of the query string) and the request body. The sample request includes a single parameter in both locations:

An HTTP request has parameters that are URL encoded, but you should collect the raw values. In addition to the request parameters, every oauth_* parameter needs to be included in the signature, so collect those too. Here are the parameters from authorizing a request:

const uuid = require('uuid');const queryParameters = {
offset:0,
limit:100,
filter:"status='active'"
}
const oauth_timestamp = Math.floor(Date.now() / 1000);const oauth_nonce = uuid.v1(); const parameters = {
...queryParameters,
oauth_consumer_key:"soni_pandey",
oauth_signature_method:"HMAC-SHA1",
oauth_timestamp: oauth_timestamp,
oauth_nonce: oauth_nonce,
oauth_version:"1.0"
}

In requesting url, there is 3 query-parameters (offset, limit and filter) apart from oauth_* parameters.

These values need to be encoded into a single string, which will be used later on. The process to build the string is very specific:

  1. Percent encode every key and value that will be signed.
  2. Sort the list of parameters alphabetically [1] by encoded key [2].
  3. For each key/value pair:
  4. Append the encoded key to the output string.
  5. Append the ‘=’ character to the output string.
  6. Append the encoded value to the output string.
  7. If there are more key/value pairs remaining, append a ‘&’ character to the output string.

We have followed this Javascript steps for collecting parameters. This looks like —

let ordered = {};
Object.keys(parameters).sort().forEach(function(key) {
ordered[key] = parameters[key];
});
let encodedParameters = '';for (k in ordered) {
const encodedValue = escape(ordered[k]);
const encodedKey = encodeURIComponent(k);
if(encodedParameters === ''){
encodedParameters += encodeURIComponent(`${encodedKey}=${encodedValue}`)
}
else{
encodedParameters += encodeURIComponent(`&${encodedKey}=${encodedValue}`);
}
}
console.log(encodedParameters);

Parameter string

The following parameter string will be produced by repeating these steps with the parameters collected above:

filter=status%3D%27active%27&limit=100&oauth_consumer_key=soni_pandey&oauth_nonce=adf979a5b9e6&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1587025108&oauth_version=1.0&offset=0

Creating the signature base string

The three values collected so far must be joined to make a single string, from which the signature will be generated. This is called the signature base string by the OAuth specification.

To encode the HTTP method, base URL, and parameter string into a single string:

  1. Convert the HTTP Method to uppercase and set the output string equal to this value.
  2. Append the ‘&’ character to the output string.
  3. Percent encode the URL and append it to the output string.
  4. Append the ‘&’ character to the output string.
  5. Percent encode the parameter string and append it to the output string.

We have followed this Javascript steps for creating the signature base string.

const method = 'GET';const base_url = 'https://schoolwebsite.org/campus/oneroster/schoolName/learningdata/v1/schools';const encodedUrl = encodeURIComponent(base_url);encodedParameters = encodeURIComponent(encodedParameters); // encodedParameters which we generated in last step.const signature_base_string = `${method}&${encodedUrl}&${encodedParameters}`console.log(signature_base_string)

This will produce the following signature base string:

GET&https%3A%2F%2Fschoolwebsite.org%2Fcampus%2Foneroster%2FschoolName%2Flearningdata%2Fv1%2Fschools&filter%3Dstatus%253D%2527active%2527%26limit%3D100%26oauth_consumer_key%3Dsoni_pandey%26oauth_nonce%3Dadf979a5b9e6%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1587025108%26oauth_version%3D1.0%26offset%3D0

Getting a signing key

Consumer key and Secret key has been provided by provider.

const secret_key = `e7zjz7ZN2U4ZRhfV3WpwPA`;

The value which identifies the account your application is acting on behalf of is called the OAuth token secret.

There is no secret token generated in our case. So our signing key will look like -

const signing_key = `${secret_key}&`; //as token is missing in our case.

Calculating the signature

Finally, the signature is calculated by passing the signature base string and signing key to the HMAC-SHA1 hashing algorithm.

const crypto = require('crypto');const oauth_signature = crypto.createHmac("sha1", signing_key).update(signature_base_string).digest().toString('base64');console.log(oauth_signature);

oauth_signature will look like —

WupKbjeG8qoSSdgYTTod04lad/c=

Encode this oauth_signature to use in Authorization header.

const encoded_oauth_signature = encodeURIComponent(oauth_signature);console.log(encoded_oauth_signature);WupKbjeG8qoSSdgYTTod04lad%2Fc%3D

Now, this is the time to take a look, how our authorization header will look like -

OAuth oauth_consumer_key='soni_pandey',oauth_signature_method='HMAC-SHA1',oauth_timestamp='1587025108',oauth_nonce='adf979a5b9e6',oauth_version='1.0',oauth_signature='WupKbjeG8qoSSdgYTTod04lad%2Fc%3D'

Conclusion

Here we have learned about how we have generated oauth_signature with the current timestamp and unique nonce value. Here is the source code. You can use this in any project. Make sure that you have made changes to configuration file(config.js). You can reach out to me for any doubt and suggestions.

References -

  1. https://developer.twitter.com/en/docs/basics/authentication/oauth-1-0a/creating-a-signature
  2. https://docs.akana.com/cm/api_oauth/aaref/Ref_OAuth_AuthorizationHeader_10a.htm
  3. https://www.varonis.com/blog/what-is-oauth/

--

--

Soni Pandey

I am a Node.js Developer and eager to learn new technology. I blog, tweet & read whenever I can.