Skip to content

Instantly share code, notes, and snippets.

@paulrobertlloyd
Last active October 1, 2019 07:35
Show Gist options
  • Save paulrobertlloyd/22a71f5db3dfa75c9df45e1c17a10521 to your computer and use it in GitHub Desktop.
Save paulrobertlloyd/22a71f5db3dfa75c9df45e1c17a10521 to your computer and use it in GitHub Desktop.
Express application routes - Authentication using IndieAuth
// Express
const express = require('express');
const router = new express.Router();
// IndieAuth
const IndieAuth = require('indieauth-helper');
const auth = new IndieAuth({
secret: 'topSecretString'
});
// Authenticate middleware
const authenticate = async (req, res, next) => {
const {app} = req.app.locals; // Application (this server) data
const {pub} = req.app.locals; // Publication (remote website) data
// If current session contains authenticated `me`, proceed to next middleware
if (req.session && req.session.me === pub.url) {
return next();
}
// Set auth options
auth.options.clientId = app.url;
auth.options.redirectUri = `${req.protocol}://${req.get('host')}${req.path}`;
auth.options.me = pub.url;
auth.getRelsFromUrl(pub.url).then(rels => {
console.log('getRelsFromUrl, rels', rels);
}).catch(error => console.log(error));
// If redirected from IndieLogin callback, authenticate user and request access token
const {code} = req.query;
const {state} = req.query;
if (code && state) {
auth.verifyCode(code).then(me => {
console.log('verifyCode, me', me);
req.session.me = me;
}).catch(error => console.error(error));
auth.getToken(code).then(token => {
console.log('getToken, me', token);
req.session.accessToken = token;
}).catch(error => console.error(error));
}
// No current session
res.redirect(`sign-in?redirect=${req.path}`);
};
// Public page
router.get('/',
(req, res) => {
res.render('index');
}
);
// Private page
router.get('/private',
authenticate,
(req, res) => {
res.render('private');
}
);
// Sign in page
router.get('/sign-in', (req, res) => {
const {app} = req.app.locals;
const redirect = req.query.redirect || '';
res.render('sign-in', {
// Values required for sign in form
client_id: app.url,
redirect_uri: app.url + redirect,
state: auth.generateState()
});
});
// Sign out page
router.get('/sign-out', (req, res) => {
req.session.destroy();
res.redirect('/');
});
module.exports = router;
{% extends "_default.njk" %}
{% set title = "Sign in" %}
{% block content %}
<form action="https://indielogin.com/auth" method="get">
<fieldset>
<legend>{{ __("Sign in") }}</legend>
<div>
<label for="url">{{ __("Web address") }}</label>
<input id="url" type="url" name="me" value="{{ pub.url }}"/>
<input type="hidden" name="client_id" value="{{ client_id }}"/>
<input type="hidden" name="redirect_uri" value="{{ redirect_uri }}"/>
<input type="hidden" name="scope" value="create"/>
<input type="hidden" name="state" value="{{ state }}"/>
</div>
<button type="submit">{{ __("Sign in") }}</button>
</fieldset>
</form>
{% endblock %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment