Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save aaronksaunders/d2781e1f4db5713e3a9f to your computer and use it in GitHub Desktop.
Save aaronksaunders/d2781e1f4db5713e3a9f to your computer and use it in GitHub Desktop.

To implement API authentication in KeystoneJS, you need the following:

For key based authentication

  • Middleware that validates the key in the request body or a header

For session based authentication

  • An endpoint that handles signin
  • An endpoint that handles signout
  • Middleware that validates the session

Examples of both methods are below.

Note that the code in each file below would normally be spread across several files, depending on your project organisation, e.g. route handlers in a /routes/api/... folder, and route bindings in /routes/index.js.

// check that the key has been provided in the request body,
// could also be a header
function checkAPIKey(req, res, next) {
// you would have the key in an env variable or load it from
// your database or something.
if (req.body.apiKey === SECRET_API_KEY) return next();
return res.status(403).json({ 'error': 'no access' });
}
// then bind that middleware in your routes before any paths
// that should be protected
app.all('/api*', checkAPIKey);
// the rest of your api endpoints go below here, e.g.
app.get('/api/stuff', getStuff);
// create a route that handles signin
function signin(req, res) {
if (!req.body.username || !req.body.password) return res.json({ success: false });
keystone.list('User').model.findOne({ email: req.body.username }).exec(function(err, user) {
if (err || !user) {
return res.json({
success: false,
session: false,
message: (err && err.message ? err.message : false) || 'Sorry, there was an issue signing you in, please try again.'
});
}
keystone.session.signin({ email: user.email, password: req.body.password }, req, res, function(user) {
return res.json({
success: true,
session: true,
date: new Date().getTime(),
userId: user.id
});
}, function(err) {
return res.json({
success: true,
session: false,
message: (err && err.message ? err.message : false) || 'Sorry, there was an issue signing you in, please try again.'
});
});
});
}
// you'll want one for signout too
function signout(req, res) {
keystone.session.signout(req, res, function() {
res.json({ 'signedout': true });
});
// also create some middleware that checks the current user
// as long as you're using Keystone's session management, the user
// will already be loaded if there is a valid current session
function checkAuth(req, res, next) {
// you could check user permissions here too
if (req.user) return next();
return res.status(403).json({ 'error': 'no access' });
}
// add an API endpoint for signing in _before_ your protected routes
app.post('/api/signin', signin);
app.post('/api/signout', signout);
// then bind that middleware in your routes before any paths
// that should be protected
app.all('/api*', checkAuth);
// the rest of your api endpoints go below here, e.g.
app.get('/api/stuff', getStuff);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment