Skip to content

Instantly share code, notes, and snippets.

@peter
Created February 20, 2014 19:24
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save peter/9121297 to your computer and use it in GitHub Desktop.
Save peter/9121297 to your computer and use it in GitHub Desktop.
Force SSL for Express app on Heroku
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Hooking up the middleware with the express app
// In app.js
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var forceSSL = require('../middleware/ssl').force(config.hostname);
if ('production' == app.get('env')) {
app.use(forceSSL);
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Middleware
// In middleware/ssl.js
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var redirectUrl = exports.redirectUrl = function(protocol, hostname, url) {
return protocol === 'https' ? null : ('https://' + hostname + url);
};
exports.force = function(hostname) {
return function(req, res, next) {
var redirectTo = redirectUrl(req.header('X-Forwarded-Proto'), hostname, req.url);
if (redirectTo) {
res.redirect(301, redirectTo);
} else {
next();
}
};
};
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Mocha test
// In test/middleware/ssl_test.js
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var _ = require('lodash'),
assert = require('assert'),
sinon = require('sinon'),
ssl = require('../../lib/middleware/ssl');
describe('middleware/ssl', function() {
describe('redirectUrl', function() {
it('returns an https url if protocol is http', function() {
assert.equal('https://api.naturkartan.se/some/url', ssl.redirectUrl('http', 'api.naturkartan.se', '/some/url'));
});
it('returns null if protocol is https', function() {
assert.equal(null, ssl.redirectUrl('https', 'api.naturkartan.se', '/some/url'));
});
});
describe('force', function() {
it('calls next if request is secure', function() {
var req = {header: sinon.stub().withArgs('X-Forwarded-Proto').returns('https')},
res = {},
next = sinon.mock().once();
ssl.force('api.naturkartan.se')(req, res, next);
next.verify();
});
it('redirects to https if request is not secure', function() {
var req = {url: '/foobar', header: sinon.stub().withArgs('X-Forwarded-Proto').returns('http')},
res = {redirect: sinon.mock().withArgs(301, 'https://api.naturkartan.se/foobar').once()},
next = {};
ssl.force('api.naturkartan.se')(req, res, next);
res.redirect.verify();
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment