api-key-auth icon indicating copy to clipboard operation
api-key-auth copied to clipboard

Example Usage: Misleading?

Open markfaine opened this issue 4 years ago • 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?

markfaine avatar Jul 17 '21 18:07 markfaine

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

arkerone avatar Jul 17 '21 18:07 arkerone

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.

mxbranson avatar Apr 13 '22 09:04 mxbranson

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();

mxbranson avatar Apr 14 '22 08:04 mxbranson