HMAC Authentication with dynamic tokens

Hi Everyone,

Hoping you might be able to help with guiding me on how to get dynamic tokens that are generated using HMAC. The API I’m busy with has been set up for testing through Postman, but I’d like to automate using RFW. Authentication consists of a Key, Secret and Auth token. The key and secret always remain the same and are set up using environment variables. There is a prerequest script at collection level that runs to generate a new token each time a call is executed. That token is then passed into an Authorization variable in the header of each request. The key, secret and token aren’t passed to the URL, so setting params or data breaks the call execution and results in 500s.
Does anyone have any suggestions please?
The code below is an adaptation of what I’ve used previously for standard JWT authentication, but when I execute now, it’s throwing a 401:

create session  mysession  ${BASE_URL}
${data1}=  create dictionary  Key=${KEY}  Secret=${SECRET}   
${headers}=  create dictionary  Content-Type=application/json
${resp}=  GET On Session  mysession  /api/v2/Batch  headers=${headers}  data=${data1}
${accessToken}=    evaluate    $resp.json().get("token")
Log to Console  ${accessToken}
${Bearer}=  set variable  LL
${token}=  catenate  LL  ${accessToken}
Log to Console     ${token}
Set Suite Variable  ${token}

Hi Jasmine,

I’ll try to help, I’ll assume for now this part of your script is working and you are getting an access token?

create session  mysession  ${BASE_URL}
${data1}=  create dictionary  Key=${KEY}  Secret=${SECRET}   
${headers}=  create dictionary  Content-Type=application/json
${resp}=  GET On Session  mysession  /api/v2/Batch  headers=${headers}  data=${data1}
${accessToken}=    evaluate    $resp.json().get("token")
Log to Console  ${accessToken}

If not perhaps what you need to do is (I’m guessing here):

${headers}=  create dictionary  Content-Type=application/json  Key=${KEY}  Secret=${SECRET}

After you get your access token, based on your description I think you then need to start with Set To Dictionary to add to the headers variable then use Update Session to update the session, something like this:

Set To Dictionary	${headers}	LL=${accessToken}
Update Session   mysession   headers=${headers}

As for the rest of the script, i’m not sure what your doing there, I think your prepending LL to the accessToken? so that might need to go before the Set To Dictionary, and you then might need to use ${token} instead of ${accessToken} in Set To Dictionary

${Bearer}=  set variable  LL
${token}=  catenate  LL  ${accessToken}
Log to Console     ${token}
Set Suite Variable  ${token}

Not sure how much help this was, but if you can show me the working raw request & responses from postman I might be able to help better, as I’m just guessing at the moment.

Dave.

Hi Jasmine,

So I understand your problem, you need to use the key and secret to generate the token before you send the first request, fortunately they’ve given you a code example of how to generate the token but it’s looks like it’s in in javascript? or ecmascript?

I am not at an advanced level in these languages, but can read them to have some understanding of what is happening. there are 2 parts to that script, the functions at the top and the variables at the bottom that get values from postman and then generate the auth header token and push that back to postman.

As robot framework doesn’t run javascript or ecmascript directly, I can think of 2 options for you, both have pro’s and con’s:

  1. Rewrite these functions as python functions so that robot framework can call the python function and generate the token for you.

  2. Use Js2Py to call the javascript / ecmascript from python
    (some more example of usage here Run JavaScript In Python With Code For Beginners | Program Solve )

Personally i’m leaning towards the second option, that way you are using their code to generate the token but it’s likely to be slower in the test execution, hopefully not a lot slower, it also means you have another dependancy. but on the upside if they change the token generation formula you can just drop in the new version of their code.

I would suggest creating a python library for robot framework (creating test library class or module) probably called HMAC (class & python file name) with a single function inside called something like create_auth_header(method, url, body, key, secret) this python function would use Js2Py to call the javascript/ecmascript function createAuthHeader passing the values straight through, and return the result.
Then in your robot framework test suite you just import the HMAC library and call the python function as a keyword something like this:

${TOKEN}=    Create Auth Header    GET    ${BASE_URL}/api/v2/Batch    ${EMPTY}    ${KEY}    ${SECRET}

Note: python function name of create_auth_header translates as robot framework keyword Create Auth Header that wasn’t clear to me when I created my first python library.

Then it’s just a simple matter of adding the token into the headers.

Not sure your programming skills, you may need help if there, this is not the easiest thing to implement, but done the way I suggested you’ll have a reusable keyword that you can use for many many test cases. If you’re not strong on python coding try finding some one in your org who is to help you, but if you manage to get this all working yourself it’ll be a great learning experience.

Hope this helps,

Dave.

Hello Damies,

I have a couple of questions, which I would be grateful if you help me with:

  1. how can I exclude the postman methods from the js file before evaluating it
  2. how can I add the correct headers to this js file to have the correct value of the auth token?

meaning, how can I edit this js file before evaluating it

Appreciating you help

Greetings Jamine,

which one of the two solutions worked for you?

Thanks

Hi Ahmed,

Sorry man, I stopped working on this over a year ago. Didn’t get past this point.

Good luck!

Hi Ahmed,

Wow that post you replied to is nearly 1.5 years ago, I don’t even remember it.

Skimming over what I wrote, I’m not sure if it was even a solution, the way I worded it it was more a guess of where to look for a solution rather than something I have done before.

Personally I probably wouldn’t do things this way unless it was a last resort, I’d probably try and emulate what the java script does with robot framework keywords or python.

Dave.