arkerone/api-key-auth

Example Usage: Misleading?

Opened this issue · 3 comments

This looks like exactly what I need for securing my simple API, however, the example usage makes it seem like I can easily set an API key, pass that as a Bearer token and be done with it, however, I'm starting to suspect that the HTTP signature signing is not optional. Is this correct? If so, why isn't that part of the example?

What example are you talking about? The signature is required and must be create by the client. I detailed the process here : https://github.com/arkerone/api-key-auth/blob/master/signature.md

I got this to work using Postman for easy testing.
I had date issues at first and needed to add 2 hours for my location so remove that add(2,"hours") from the code if you see 'expired' errors.
The pm.environment.set() stuff is how you pragmatically set variables in Postman.

(don't include backticks ``)

  1. Create a variable in Auth's API KEY: key=authorization, value=Signature keyId="123456789",algorithm="hmac-sha256",headers="(request-target) date",signature="{{signature}}"
  2. Added 'date' variable to Headers: date: {{currentdate}} as a minimum. Expand this as suggested to increase security.
  3. Created a bunch of pre-req script to generate the variables:
var moment = require('moment');
var cryptojs = require("crypto-js");

var currentdate = moment().add(2,"hour").format(('ddd, D MMM Y hh:m:ss'));

var headerString = "(request-target): get /protected\ndate: "+currentdate;
console.log(headerString);

var signature = cryptojs.HmacSHA256(headerString,'secret1').toString(cryptojs.enc.Base64);

pm.environment.set('currentdate', currentdate);
pm.environment.set('signature', signature);

  1. Check the console output to see your sent headers
  2. You should see a 200 response with Hello app1 on success.

Here's a nodejs client.js example:

var APIKEY = "123456789";
var APISECRET = "secret1"

var http = require('http');
var moment = require('moment');
var cryptojs = require("crypto-js");

var currentdate = moment().format(('ddd, D MMM Y hh:m:ss'));
var signheader = "(request-target): get /protected\ndate: "+currentdate;
var signature = cryptojs.HmacSHA256(signheader,APISECRET).toString(cryptojs.enc.Base64);
var authheader = 'Signature keyId=\"'+APIKEY+'\",algorithm=\"hmac-sha256\",headers=\"(request-target) date\",signature=\"'+signature+'\"';

// make a request

  var options = {
    port: 8080,
    host: '127.0.0.1',
    path: '/protected',
    method: 'get',
    headers: {
        "date": currentdate,
        "authorization": authheader
    }
  };

//console.log(JSON.stringify(options));

  var req = http.get(options,function(res){
  res.setEncoding('utf8');
  console.log(res.statusCode);
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });

}).on('error', function(e) {
  console.log("Got error: " + e.message);
});
req.end();