Skip to content

Instantly share code, notes, and snippets.

@jdheywood
Last active January 28, 2020 12:48
Show Gist options
  • Save jdheywood/c7f4b51c9b021da12ce952729ccd4187 to your computer and use it in GitHub Desktop.
Save jdheywood/c7f4b51c9b021da12ce952729ccd4187 to your computer and use it in GitHub Desktop.
Example of simple token authorisation middleware for use in Express application, with unit test (depends on service to get tokens from env vars)
/* eslint-disable consistent-return */
import { getAPIAuthToken } from '../services/environment';
const authorisation = () => (req, res, next) => {
if (!req.headers.authorization) {
return res.status(401).json({ error: 'Credentials missing' });
}
const clientToken = req.headers.authorization;
const serverToken = getAPIAuthToken();
if (clientToken !== serverToken) {
return res.status(403).json({ error: 'Credentials invalid' });
}
next();
};
export default authorisation;
/* eslint-enable consistent-return */
/* eslint-disable arrow-body-style */
import { getAPIAuthToken } from '../services/environment';
import authorisation from '../middleware/authorisation';
describe('Middleware', () => {
describe('authorisation', () => {
// mock out our request, response and next functions to test our middleware
const mockRequest = (token) => {
return {
headers: {
authorization: token,
},
};
};
const mockResponse = () => {
const res = {};
res.status = jest.fn().mockReturnValue(res);
res.json = jest.fn().mockReturnValue(res);
return res;
};
const mockNext = () => {
return jest.fn();
};
test('should respond with 401 if no authorization header included in request', () => {
const req = mockRequest();
const res = mockResponse();
const next = mockNext();
authorisation()(req, res, next);
expect(res.status).toHaveBeenCalledWith(401);
expect(res.json).toHaveBeenCalledWith({ error: 'Credentials missing' });
});
test('should respond with 403 if authorization token does not match server token', () => {
const req = mockRequest('invalid-token-value');
const res = mockResponse();
const next = mockNext();
authorisation()(req, res, next);
expect(res.status).toHaveBeenCalledWith(403);
expect(res.json).toHaveBeenCalledWith({ error: 'Credentials invalid' });
});
test('should call the next function in req/res cycle if tokens match', () => {
const validToken = getAPIAuthToken();
const req = mockRequest(validToken);
const res = mockResponse();
const next = mockNext();
authorisation()(req, res, next);
expect(next).toHaveBeenCalled();
});
});
});
/* eslint-enable arrow-body-style */
const TokenMap = {
development: process.env.TOKEN_DEV,
staging: process.env.TOKEN_STG,
production: process.env.TOKEN_PROD,
}
export function getAPIAuthToken() {
const token = TokenMap[process.env.NODE_ENV];
return token ? token : `no-token-for-env-${process.env.NODE_ENV}`;
}
export default { getAPIAuthToken };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment