HTTP Hawk Authentication Scheme

9.0.2 · maintenance · verified Tue Apr 21

Hawk is a Node.js library implementing the HTTP Hawk Authentication Scheme, a robust mechanism for making authenticated HTTP requests with partial cryptographic verification. It uses a message authentication code (MAC) algorithm to cover the HTTP method, request URI, host, and optionally the request payload, providing an alternative to HTTP Digest access authentication. Developed by Mozilla, the package is currently at version 9.0.2. It is in a 'maintenance mode' where no new features are added, and only security-related bug fixes are applied, with v9.0.2 announced as the final release. Key differentiators include its focus on two-legged client-server authentication (not OAuth delegation) and its history of ownership by hueniverse, then @hapi, and now Mozilla.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates a basic Hawk client-server interaction in Node.js, including server-side request authentication and client-side header generation.

import { Server, Client } from 'hawk';
import http from 'http';

const credentials = {
  id: process.env.HAWK_ID ?? 'dh37fgj492je',
  key: process.env.HAWK_KEY ?? 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn',
  algorithm: 'sha256' as const,
};

const credentialsLookup = (id: string, callback: (err: Error | null, credentials?: typeof credentials) => void) => {
  if (id === credentials.id) {
    return callback(null, credentials);
  }
  callback(new Error('Invalid credentials id'));
};

const server = http.createServer(async (req, res) => {
  if (req.url === '/auth-resource') {
    try {
      const authResult = await Server.authenticate(req, credentialsLookup, {});
      console.log('Server authenticated:', authResult.credentials.id);
      res.writeHead(200, { 'Content-Type': 'application/json' });
      res.end(JSON.stringify({ message: 'Authenticated resource access', user: authResult.credentials.user }));
    } catch (err: any) {
      console.error('Server authentication failed:', err.message);
      res.writeHead(401, { 'WWW-Authenticate': 'Hawk' });
      res.end('Authentication Required');
    }
  } else {
    res.writeHead(404);
    res.end('Not Found');
  }
});

server.listen(8000, '127.0.0.1', () => {
  console.log('Server running at http://127.0.0.1:8000/');

  // Client example
  const requestOptions = {
    host: '127.0.0.1',
    port: 8000,
    path: '/auth-resource',
    method: 'GET',
    headers: {},
  };

  const header = Client.header(requestOptions.path, requestOptions.method, { credentials });
  requestOptions.headers = { ...requestOptions.headers, Authorization: header.field };

  const clientReq = http.request(requestOptions, (clientRes) => {
    let data = '';
    clientRes.on('data', (chunk) => (data += chunk));
    clientRes.on('end', () => {
      console.log(`Client received status: ${clientRes.statusCode}`);
      console.log(`Client received body: ${data}`);
    });
  });
  clientReq.on('error', (e) => console.error(`Client request error: ${e.message}`));
  clientReq.end();
});

view raw JSON →