Recombee Docs
Visit recombee.comStart Free
docs20User Documentation
adminuiAdmin UI
reql32ReQL
codeAPI Clients & Integrations
cookhatScenario Recipes
suitcaseMisc

Authentication (HMAC)

The authentication is already implemented in the API clients (SDKs).

HMAC-based authentication is the single preferred way of authentication to Recombee APIs.

Thanks to the nature of our APIs, our authentication is based on a simple shared-secret approach with the signature generated according to the HMAC-SHA1 standard. To use HMAC-based authentication, you will need a token, which you can obtain in the Recombee Admin UI.

In the case of a server-side implementation, use the Private Token (which needs to remain secret and known only to you and Recombee), and in the case of a client-side implementation (e.g. in a mobile app), use the Public Token (see this section for details).

There are two parameters that you need to attach to every API call:

  • hmac_timestamp - the current UTC Unix timestamp (integer)
  • hmac_sign - the signature computed from your request URI without protocol and host

Every signature has a limited lifetime (currently 10s). It is therefore important for your server time to be synchronized via NTP or other source of precise time.

For example, let's consider a call to the following URL:

http://rapi.recombee.com/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7

The initial input to the signing method does not contain the protocol and host parts. We'll also add the hmac_timestamp parameter:

/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7&hmac_timestamp=1396859079

We then compute the signature of the above string and append it as the hmac_sign parameter. The result should then look like this:

/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7&hmac_timestamp=1396859079&hmac_sign=c608b597456d0760aee0e5a95017c63a8a24b4eb

Hash examples

To see whether you are hashing properly, you can try to hash the following strings and verify the results:

TOKEN = "gahpiev6eighaig1aek4ujietheiXeengae3Ohqu9iecutheof5rooxeigheel8G"
StringHash
Hello world1291b164d8332792233dcc8ce94e1c9ea6113fb8
/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7&hmac_timestamp=1398463889090eafba456488622a6d6f0dc37d3a1508536338

As mentioned above, the hash is calculated from the URL with the hmac_timestamp and without the domain or protocol.

Example of a correct hash string:

/recombee/items/9346/recomms/?count=5
&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7
&hmac_timestamp=1398463889

Example of an incorrect hash string:

https://rapi.recombee.com/recombee/items/9346/recomms/?count=5
&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7
&hmac_timestamp=1398463889

Authentication of Client-Side Requests

The same authentication method is used also for client-side (frontend) requests.

The differences are as follows:

  • The Public Token is used for signing,
  • The parameters have different names - use frontend_timestamp instead of hmac_timestamp and frontend_sign instead of hmac_sign,
  • The RAPI endpoint is at client-rapi.recombee.com.

See this example.

Postman

If you want to call the Recombee API using Postman, you can use the following script to authenticate your requests: https://github.com/Pazekal90/recombee-SHA1-HMAC-Postman-Pre-request-Script.

Example Implementations

The description itself can be a bit cumbersome, but the actual implementations are very simple and straightforward:

Python

import time
import hmac
from hashlib import sha1

key = 'gahpiev6eighaig1aek4ujietheiXeengae3Ohqu9iecutheof5rooxeigheel8G'

url = '/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7'\
      '&hmac_timestamp=%s' % int(time.time())

sign = hmac.new(str.encode(key), str.encode(url), sha1).hexdigest()

print('%s&hmac_sign=%s' % (url, sign))

Ruby

require 'securerandom'
require 'digest/hmac'

KEY = "gahpiev6eighaig1aek4ujietheiXeengae3Ohqu9iecutheof5rooxeigheel8G"

url = '/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7' +
      "&hmac_timestamp=#{Time.now.utc.to_i}"

sign = Digest::HMAC.hexdigest(url, KEY, Digest::SHA1)

puts "#{url}&hmac_sign=#{sign}"

PHP

  <?php

  $key = 'gahpiev6eighaig1aek4ujietheiXeengae3Ohqu9iecutheof5rooxeigheel8G';

  $url = '/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7';
  $url = $url . '&hmac_timestamp=' . time();

  $sign = hash_hmac("sha1", $url, $key);

  echo $url . "&hmac_sign=" . $sign;
  ?>

Java

import org.apache.commons.codec.binary.Hex;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

String key = "gahpiev6eighaig1aek4ujietheiXeengae3Ohqu9iecutheof5rooxeigheel8G";

String url = "/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7"+
                "&hmac_timestamp="+System.currentTimeMillis() / 1000;

Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec secret = new SecretKeySpec(key.getBytes(),"HmacSHA1");
mac.init(secret);
byte[] rawHmac = mac.doFinal(url.getBytes());
String sign = Hex.encodeHexString(rawHmac);

System.out.println(url+"&hmac_sign="+sign);

JavaScript

Using sha1.js from jsSHA.

<head>
  <script
    src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/2.4.2/sha.js"
    integrity="sha512-aNuJL9dGmxptdarUqHqErH4MhgsJR0exQrlTRvCWWfZVwtB8El4iHpr6v+1ftov/7RAczXGCTDQQteAEaOzj6w=="
    crossorigin="anonymous"
  ></script>
</head>

<body>
  <script type="text/javascript">
    const key = 'gahpiev6eighaig1aek4ujietheiXeengae3Ohqu9iecutheof5rooxeigheel8G';
    let url =
      '/recombee/items/9346/recomms/?count=5&targetUserId=fb2fbe12-9f69-45a1-9fc0-df0c1592e4c7';
    url =
      url +
      (url.indexOf('?') == -1 ? '?' : '&') +
      'frontend_timestamp=' +
      parseInt(new Date().getTime() / 1000);

    const shaObj = new jsSHA('SHA-1', 'TEXT');
    shaObj.setHMACKey(key, 'TEXT');
    shaObj.update(url);

    url = url + '&frontend_sign=' + shaObj.getHMAC('HEX');

    document.write(url);
  </script>
</body>
© Copyright 2024, Recombee s.r.o
docs.recombee.com