UNPKG

simple-google-openid

Version:

A simple library for using Google as the authenticator of your application's users.

107 lines (88 loc) 2.66 kB
/* * gets JWT id_token from query, verifies it against google certificates * sets req.user to the payload of the token * this module does nothing if req.user is already set * * verifies that the token isn't expired, that the issuer is google, * and also verifies the audience is the given client_ID */ 'use strict'; const GoogleAuth = require('google-auth-library'); const profile = require('./profile'); const log = require('./log'); const auth = new GoogleAuth.OAuth2Client(); function initialize(clientId) { if (!clientId) { throw new Error('CLIENT ID is required: checking JWT without a CLIENT ID is insecure!'); } const verifyToken = async (idToken) => { try { const verifyOptions = { idToken, audience: clientId, }; const login = await auth.verifyIdToken(verifyOptions); const payload = login.getPayload(); log('payload', JSON.stringify(payload, null, 2)); return profile.parse(payload); } catch (e) { log('error verifying token', e); return null; } }; const middleware = async function SimpleGoogleOpenIDMiddleware(req, res, next) { if (req.user) { next(); return; } const token = getAuthToken(req); if (token) { req.user = await verifyToken(token); } next(); }; middleware.guardMiddleware = guardMiddleware; middleware.verifyToken = verifyToken; return middleware; }; /* * middleware that requires req.user to exist, otherwise returns * 401 Unauthorized * WWW-Authenticate: Bearer realm="example" */ function guardMiddleware(options) { options = options || {}; const realm = options.realm || 'jwt'; if (realm.indexOf('"') >= 0) { throw new Error('authentication realm must not contain a double quote!'); } return function (req, res, next) { if (!req.user) { if (realm) res.set('WWW-Authenticate', `Bearer realm="${realm}"`); res.sendStatus(401); } else { next(); } }; } // adapted from https://github.com/auth0/express-jwt/blob/4861bbb9d906f8fbd8c494fe2dbc4fda0d7865c6/lib/index.js#L62-70 function getAuthToken(req) { let token; if (req.headers && req.headers.authorization) { const parts = req.headers.authorization.split(' '); if (parts.length === 2) { const scheme = parts[0]; const credentials = parts[1]; if (/^Bearer$/i.test(scheme)) { token = credentials; } } } if (!token && req.query.id_token) { token = req.query.id_token; } return token; } module.exports = initialize; module.exports.guardMiddleware = guardMiddleware; module.exports.getAuthToken = getAuthToken;