1.0.2 • Published 5 years ago

passport-hmac-simple v1.0.2

Weekly downloads
1
License
MIT
Repository
bitbucket
Last release
5 years ago

passport-hmac-simple

HMAC authentication for Passport and Node.js, complete with client.

Besides doing the proper hashing, it also uses timestamps to prevent replay attacks.

Server

// We use mongoose as an example, but feel free to store the user
// however you like.
//
// Example Schema: {publicKey: 'XXX', privateKey: 'YYY'}
//
const User = require('mongoose').model('User');

const passport = require('passport');
const HmacStrategy = require('passport-hmac-simple').Strategy;

// Do the regular passport initialization, then call...

passport.use(new HmacStrategy(async function(publicKey, done) {
    try {
        let user = await User.findOne({publicKey});

        if (!user || !user.privateKey)
            return done(null, false);

        done(null, user, user.privateKey);
    }
    catch (e) {
        done(e);
    }
}));

// ...now, set up and use passport as normal.

Client

The same client code should work for both Node.js require() and simple javascript tags.

Node.js

const Hmac = require('passport-hmac-simple').Hmac;

Javascript

You'll need Fetch API and CryptoJS in order to use the client browser side. If your browser doesn't support Fetch API (cough cough IE), you'll need a (polyfill)https://github.com/github/fetch.

<!-- Make this file to your page however you like. -->
<script src="passport-hmac-simple/lib/Hmac.js"></script>

GET, DELETE

var PUBLIC_KEY = 'xyz123';
var PRIVATE_KEY = 'Thisisasecret';

var hmac = new Hmac(PUBLIC_KEY, PRIVATE_KEY);

hmac.get(   // or: hmac.delete
    '/api/endpointUrl?id=123',
    function success(json) { ... },
    function error(err) { ... }
);

POST, PUT, PATCH

var PUBLIC_KEY = 'xyz123';
var PRIVATE_KEY = 'Thisisasecret';
var hmac = new Hmac(PUBLIC_KEY, PRIVATE_KEY);


hmac.post(      // or: hmac.put, etc.
    '/api/endpointUrl',
    {a: 1, b: 2},   // Pass the object, not the JSON string
    function success(json) { ... },
    function error(err) { ... }
);

Algorithm Pseudocode

You shouldn't need any of this to use the module, but it's here if you want it.

GET, DELETE

Full URL = URL + AddQueryString("timestamp", now.valueOf().toString())

InfoToSign = Method + "\n" +
    "\n" +
    "\n" +
    now.toUTCString() + "\n" +
    Path

HMAC = HMAC-SHA1(InfoToSign as UTF-8, PrivateKey) To Hex
base64HMAC = base64(HMAC)
Authorization Header = "hmac PublicKey:base64HMAC"

POST, PUT, PATCH

Only application/json is currently accepted as a content type.

Content-MD5 is set solely through the (similarly named) HTTP header. If it's wrong or missing, authentication will fail.

Full URL = URL + QueryString("timestamp", now.valueOf().toString())

InfoToSign = Method + "\n" +
    ContentType + "\n" +
    Content-MD5 + "\n" +
    now.toUTCString() +
    Path

HMAC = HMAC-SHA1(InfoToSign, PrivateKey, UTF-8) To Hex
base64HMAC = base64(HMAC)
Authorization Header = "hmac PublicKey:base64HMAC"
1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago