Integrating HERE Maps API for JavaScript with OutSystems
Sachin Jonda — 13 February 2025
11 min read
07 April 2020
As you may have noticed, we have recently introduced two new options for authentication. You can now use either an API Key or an OAuth 2.0 Bearer Token to access the HERE Location APIs. While using an API Key is straightforward, using OAuth can be bit more complicated. However, it decouples authentication from authorization, meaning that applications can access resources without exposing their credentials. In this blog post we will learn how to request a HERE OAuth Bearer Token using Python.
If you're not familiar with how OAuth works, you can think of it as a hotel key card system. If you have a card, you can use it to access your room. How do you get it? First, you have to get yourself authenticated at the hotel reception using your passport and your reservation. Then the hotel gives you a key card to access your room. However you can only access your room for the duration of your stay and access can be revoked at any time. The hotel key card in our case is a token, generated using OAuth. This token will allow us to access all HERE APIs. Lets get our token then!
Generating OAuth Token Credentials
The first step for acquiring a token is to generate OAuth credentials from developer.here.com. You can get the complete steps for generating credentials here.
The 'credentials.properties' file created from above contains two values of interest, the Access Key ID and the Access Key Secret. We will be needing them going forward.
A 'credentials.properties' file looks like this.
here.user.id = HERE-USER_IDhere.client.id = YOUR_CLIENT_IDhere.access.key.id = YOUR_ACCESS_KEYhere.access.key.secret = YOUR_ACCESS_KEY_SECREThere.token.endpoint.url = https://account.api.here.com/oauth2/token
Creating the Oauth Signature
For requesting a token, we need to pass the OAuth signature in the Authorization Header of a request. Signature plays an important role as it is used for authenticating a user or application. It requires us to create a base string containing various parameters and then pass it into an HMAC-SHA256 hashing algorithm.
Creating the Parameter String
We need 6 key-value pair for generating a signature
grant_type - Value always remains same, "client_credentials"
oauth_consumer_key - The Access Key ID value we acquired from credentials.properties file
oauth_nonce - A unique string which never repeats
oauth_signature_method - Always use "HMAC-SHA256"
oauth_timestamp - The number of seconds since the Unix epoch, in simple words, the current time
oauth_version - Always use "1.0"
The values of the parameter looks like this.
grant_type = 'client_credentials'oauth_consumer_key = 'HERE.ACCESS.KEY.ID' #From credentials.properties fileoauth_nonce = str(int(time.time()*1000))oauth_signature_method = 'HMAC-SHA256'oauth_timestamp = str(int(time.time()))oauth_version = '1.0'
The important thing here is that the type of all 6 parameters has to be string. For calculating nonce and timestamp we have used the time module of Python.
Next, we alphabetically combine all the parameters as a single string, separating each key value pair with an ampersand character ("&") and then URL-encoding it.
def create_parameter_string(grant_type, oauth_consumer_key,oauth_nonce,oauth_signature_method,oauth_timestamp,oauth_version): parameter_string = '' parameter_string = parameter_string + 'grant_type=' + grant_type parameter_string = parameter_string + '&oauth_consumer_key=' + oauth_consumer_key parameter_string = parameter_string + '&oauth_nonce=' + oauth_nonce parameter_string = parameter_string + '&oauth_signature_method=' + oauth_signature_method parameter_string = parameter_string + '&oauth_timestamp=' + oauth_timestamp parameter_string = parameter_string + '&oauth_version=' + oauth_version return parameter_string
parameter_string = create_parameter_string(grant_type, oauth_consumer_key,oauth_nonce,oauth_signature_method,oauth_timestamp,oauth_version)
encoded_parameter_string = urllib.parse.quote(parameter_string, safe='')
The parameter_string is a simple concatenated output containing key-value pair separated by an ampersand character. With the help of the urllib python library, we got our URL-encoded output in encoded_parameter_string. It looks like this.
parameter_string
grant_type=client_credentials&oauth_consumer_key=XXXXXXXXXX&oauth_nonce=1585745318447&oauth_signature_method=HMAC-SHA256&oauth_timestamp=1585745318&oauth_version=1.0
encoded_parameter_string
grant_type%3Dclient_credentials%26oauth_consumer_key%3DXXXXXXXXXX%26oauth_nonce%3D1585745318447%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1585745318%26oauth_version%3D1.0
Creating Signature Base String
Next we need to add the HTTP method (POST), base URL and encoded parameter string into a single string called base string.
url = 'https://account.api.here.com/oauth2/token'
encoded_base_string = 'POST' + '&' + urllib.parse.quote(url, safe='')encoded_base_string = encoded_base_string + '&' + encoded_parameter_string
Base string looks like this.
POST&https%3A%2F%2Faccount.api.here.com%2Foauth2%2Ftoken&grant_type%3Dclient_credentials%26oauth_consumer_key%3DXXXXXXXXXX%26oauth_nonce%3D1585747084344%26oauth_signature_method%3DHMAC-SHA256%26oauth_timestamp%3D1585747084%26oauth_version%3D1.0
POST, URL and encoded parameter string separated by ampersand ("&")
Creating Signing Key
The signing key is the URL-encoded access key secret, followed by an ampersand ("&"). The access key secret is the value of "here.access.key.secret" property in credentials.properties file.
access_key_secret = 'HERE.ACCESS.KEY.SECRET'#From credentials.properties filesigning_key = access_key_secret + '&'
Combining all to create OAuth Signature
The signature base string and the signing key created above, are passed to the HMAC-SHA256 Hashing Algorithm and the output is converted to a base64 string. Finally, we have our OAuth Signature.
def create_signature(secret_key, signature_base_string): encoded_string = signature_base_string.encode() encoded_key = secret_key.encode() temp = hmac.new(encoded_key, encoded_string, hashlib.sha256).hexdigest() byte_array = b64encode(binascii.unhexlify(temp)) return byte_array.decode()
oauth_signature = create_signature(signing_key, encoded_base_string)
encoded_oauth_signature = urllib.parse.quote(oauth_signature, safe='')
The create_signature method takes secret key and base string as an input, performs hashing, converts the output into a base64 string. Then we URL-encode the output for further usage.
Requesting Token
Once we have our signature, the rest of the process is straight forward. All we require now is to create an Authorization header for the request and then make a request.
For this, first we will combine -
oauth_consumer_key - The value of "here.access.key.id" from credentials.properties file
oauth_nonce - Already have
oauth_signature - The value of encoded_oauth_signature from above
oauth_signature_method - "HMAC-SHA256"
oauth_timestamp - Already have
oauth_version - "1.0"
and append them to a string beginning with “OAuth”.
body = {'grant_type' : '{}'.format(grant_type)}
headers = { 'Content-Type' : 'application/x-www-form-urlencoded', 'Authorization' : 'OAuth oauth_consumer_key="{0}",oauth_nonce="{1}",oauth_signature="{2}",oauth_signature_method="HMAC-SHA256",oauth_timestamp="{3}",oauth_version="1.0"'.format(oauth_consumer_key,oauth_nonce,encoded_oauth_signature,oauth_timestamp) } response = requests.post(url, data=body, headers=headers)
print(response.text)
The request body must contain grant_type value as 'client_credentials', always.
The output of the code looks like this-
{"access_token":"eyJhbGci...","token_type":"bearer","expires_in":86399}
The Complete Code
A lot of libraries are needed to be imported which are not mentioned in the above steps. So lets see how the complete code looks like.
import requests #Needed for making HTTP requestsimport time #Needed to generate the OAuth timestampimport urllib.parse #Needed to URLencode the parameter stringfrom base64 import b64encode #Needed for create_signature functionimport hmac #Needed for create_signature functionimport hashlib #Needed for create_signature functionximport binascii#Needed for create_signature function
grant_type = 'client_credentials'oauth_consumer_key = 'HERE.ACCESS.KEY.ID' #From credentials.properties fileaccess_key_secret = 'HERE.ACCESS.KEY.SECRET'#From credentials.properties fileoauth_nonce = str(int(time.time()*1000))oauth_timestamp = str(int(time.time()))oauth_signature_method = 'HMAC-SHA256'oauth_version = '1.0'url = 'https://account.api.here.com/oauth2/token'
# HMAC-SHA256 hashing algorithm to generate the OAuth signaturedef create_signature(secret_key, signature_base_string): encoded_string = signature_base_string.encode() encoded_key = secret_key.encode() temp = hmac.new(encoded_key, encoded_string, hashlib.sha256).hexdigest() byte_array = b64encode(binascii.unhexlify(temp)) return byte_array.decode() # concatenate the six oauth parameters, plus the request parameters from above, sorted alphabetically by the key and separated by "&"def create_parameter_string(grant_type, oauth_consumer_key,oauth_nonce,oauth_signature_method,oauth_timestamp,oauth_version): parameter_string = '' parameter_string = parameter_string + 'grant_type=' + grant_type parameter_string = parameter_string + '&oauth_consumer_key=' + oauth_consumer_key parameter_string = parameter_string + '&oauth_nonce=' + oauth_nonce parameter_string = parameter_string + '&oauth_signature_method=' + oauth_signature_method parameter_string = parameter_string + '&oauth_timestamp=' + oauth_timestamp parameter_string = parameter_string + '&oauth_version=' + oauth_version return parameter_string parameter_string = create_parameter_string(grant_type, oauth_consumer_key,oauth_nonce,oauth_signature_method,oauth_timestamp,oauth_version)encoded_parameter_string = urllib.parse.quote(parameter_string, safe='')encoded_base_string = 'POST' + '&' + urllib.parse.quote(url, safe='')encoded_base_string = encoded_base_string + '&' + encoded_parameter_string
# create the signing keysigning_key = access_key_secret + '&'
oauth_signature = create_signature(signing_key, encoded_base_string)encoded_oauth_signature = urllib.parse.quote(oauth_signature, safe='')
#---------------------Requesting Token---------------------body = {'grant_type' : '{}'.format(grant_type)}
headers = { 'Content-Type' : 'application/x-www-form-urlencoded', 'Authorization' : 'OAuth oauth_consumer_key="{0}",oauth_nonce="{1}",oauth_signature="{2}",oauth_signature_method="HMAC-SHA256",oauth_timestamp="{3}",oauth_version="1.0"'.format(oauth_consumer_key,oauth_nonce,encoded_oauth_signature,oauth_timestamp) } response = requests.post(url, data=body, headers=headers)
print(response.text)
Conclusion
The value of access token is our actual token, and it is valid for 24 Hour. You can use token to make all HERE API calls. Although you can continue to use API Key if you like, but if you want to go for a production environment, OAuth is the right way.
Vidhan Bhonsle
Share article
Vidhan Bhonsle
Sachin Jonda — 13 February 2025
Alberts Jekabsons — 17 December 2024
Mohini Todkari — 22 October 2024
Why sign up:
Latest offers and discounts
Tailored content delivered weekly
Exclusive events
One click to unsubscribe