Creating a Node.js Application for HERE API with OAuth 2.0 Authentication

Use HERE platform OAuth credentials to request an access token from the HERE OAuth 2.0 token endpoint, then pass the returned token as a Bearer token when calling the HERE Geocoding and Search API v1. Most OAuth failures in Node.js occur because the OAuth 1.0a signature parameters are not encoded, sorted, signed, or sent exactly as required for the token request.

Applies to
----------

Product: HERE platform
API: HERE OAuth 2.0 token endpoint
API: HERE Geocoding and Search API v1
Platform: Node.js application
Runtime: Node.js 18 or later recommended
Authentication type: HERE OAuth credentials from credentials.properties

Customer symptoms
-----------------

Customers may see one or more of the following symptoms:

The token request to HERE fails with 401 Unauthorized
The response contains oauth_problem=signature_invalid
The response contains oauth_problem=consumer_key_unknown
The Geocoding and Search API request fails with 401 Unauthorized
The application logs Error obtaining OAuth token
The application logs no geocoding results because the Bearer token was not created or was not passed correctly

Root cause
----------

HERE platform OAuth access tokens are requested by signing the token request with the access key ID and access key secret from the downloaded credentials.properties file. The token request uses OAuth parameters such as oauth_consumer_key, oauth_nonce, oauth_signature_method, oauth_timestamp, and oauth_version. If any parameter is missing, encoded incorrectly, sorted incorrectly, signed with the wrong secret, or sent in the wrong request location, HERE cannot validate the request and the token endpoint returns an authentication error.

The Geocoding and Search API call must then use the returned access_token in the HTTP Authorization header as Bearer . Passing the access key ID or secret directly to the Geocoding and Search API does not authenticate the request.

Impact
------

When the OAuth token request fails, the Node.js application cannot obtain an access token and cannot call HERE APIs that require OAuth authentication. When the token request succeeds but the Geocoding and Search API call fails, the most common causes are an expired token, a missing Authorization header, an incorrectly formatted Bearer token, or use of the wrong API endpoint.

Example project setup
---------------------

Prerequisites
-------------

Node.js installed on your machine.
A HERE platform account with credentials.properties file containing access key ID and secret.

Setting Up Your Project
-----------------------

1. Initialize a new Node.js project:

Create a new directory for your project and initialize it with npm.

<br />mkdir here-api-projectcd here-api-projectnpm init -y<br />

Install Dependencies:

Install axios for making HTTP requests and crypto for generating signatures.

<br />npm install axios<br />

Note: crypto is a built-in Node.js module, so no installation is required.

Application Structure
---------------------

Your application will consist of several functions responsible for different tasks:

generateOAuthSignature: Generates an OAuth signature required for the authentication request.
getOAuthToken: Retrieves an OAuth token from HERE.
queryGeocoderAPI: Makes a request to the HERE Geocoder API using the obtained OAuth token.
main: Orchestrates the flow by first obtaining a token, then querying the Geocoder API.

Code Explanation
----------------

### Generating OAuth Signature

The generateOAuthSignature function in the attached index.js file creates the signature required for the OAuth token request. It constructs a parameter string, creates a base string, and then generates a HMAC-SHA256 signature.

<br />function generateOAuthSignature(url, method, params, consumerKey, accessSecret) { const parameterString = Object.keys(params).sort().map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join('&'); const baseString = `${method}&${encodeURIComponent(url)}&${encodeURIComponent(parameterString)}`; const signingKey = `${accessSecret}&`; const signature = crypto.createHmac('sha256', signingKey).update(baseString).digest('base64'); return encodeURIComponent(signature);}<br />

### Obtaining an OAuth Token

The getOAuthToken function requests an OAuth token from HERE using your credentials and the signature generated by generateOAuthSignature.

<br />async function getOAuthToken() { const params = { oauth_consumer_key: oauthConsumerKey, oauth_nonce: Date.now().toString(), oauth_signature_method: 'HMAC-SHA256', oauth_timestamp: Math.floor(Date.now() / 1000).toString(), oauth_version: '1.0', grant_type: 'client_credentials', }; const encodedSignature = generateOAuthSignature(oauthTokenUrl, 'POST', params, oauthConsumerKey, accessKeySecret); const authHeader = `OAuth oauth_consumer_key="${params.oauth_consumer_key}",oauth_nonce="${params.oauth_nonce}",oauth_signature="${encodedSignature}",oauth_signature_method="${params.oauth_signature_method}",oauth_timestamp="${params.oauth_timestamp}",oauth_version="${params.oauth_version}"`; try { const response = await axios.post(oauthTokenUrl, 'grant_type=client_credentials', { headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization': authHeader } }); return response.data.access_token; } catch (error) { console.error('Error obtaining OAuth token:', error); throw error; }}`<br />

### Querying the Geocoder API

Once you have an OAuth token, you can use it to authenticate requests to HERE APIs. The queryGeocoderAPI function demonstrates querying the HERE Geocoder API with the obtained token.

<br />async function queryGeocoderAPI(query, accessToken) { try { const response = await axios.get(geocodeUrl, { params: { q: query }, headers: { Authorization: `Bearer ${accessToken}` } }); const items = response.data.items; if (items.length > 0) { const item = items[0]; // Taking the first result for simplicity console.log('Title:', item.title); console.log('ID:', item.id); console.log('Result Type:', item.resultType); console.log('Address:', JSON.stringify(item.address, null, 2)); // Pretty-print the address object console.log('Position:', JSON.stringify(item.position, null, 2)); // Pretty-print the position object console.log('MapView:', JSON.stringify(item.mapView, null, 2)); // Pretty-print the mapView object console.log('Scoring:', JSON.stringify(item.scoring, null, 2)); // Pretty-print the scoring object } else { console.log('No results found.'); } } catch (error) { console.error('Error querying Geocoder API:', error); }}`<br />

### Main Function

The main function orchestrates the process of obtaining an OAuth token and then using it to make a request to the HERE Geocoder API.

<br />async function main() { try { const accessToken = await getOAuthToken(); console.log('Obtained Access Token:', accessToken); await queryGeocoderAPI('5th Avenue New York', accessToken); } catch (error) { console.error('An error occurred:', error); }}`main();<br />

Running Your Application
------------------------

To run your application, use the following command in your terminal:

<br />node index.js<br />

Ensure you replace 'your-access-key-id' and 'your-access-key-secret' with your actual HERE credentials. Please download the full attached project source for running on your local machine.

Troubleshooting
---------------

If the token request returns 401 Unauthorized, verify that the access key ID and access key secret match the values in the downloaded HERE platform credentials.properties file. Also confirm that the OAuth signature includes grant_type=client_credentials in the signed parameters and that the same value is sent in the request body.

If the Geocoding and Search API request returns 401 Unauthorized, verify that the application sends the token as Authorization: Bearer . Do not send the OAuth authorization header used for the token request to the Geocoding and Search API.

If the response contains an empty items array, authentication succeeded but the geocoding query did not return a matching result. Try a more specific address, include city or country information, or review the query text.

Search keywords
---------------

HERE OAuth, Node.js, OAuth 2.0, HMAC-SHA256, credentials.properties, access key ID, access key secret, Geocoding and Search API, Geocoder API, Bearer token, 401 Unauthorized, signature_invalid, client_credentials, axios, account.api.here.com


Did this page help you?