├── .gitignore ├── package.json ├── index.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by http://www.gitignore.io 2 | 3 | ### Node ### 4 | lib-cov 5 | lcov.info 6 | *.seed 7 | *.log 8 | *.csv 9 | *.dat 10 | *.out 11 | *.pid 12 | *.gz 13 | 14 | pids 15 | logs 16 | results 17 | build 18 | .grunt 19 | 20 | node_modules 21 | 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "connect-google-jwt", 3 | "version": "1.0.0", 4 | "description": "Vaidate google's JWTs middleware for connect.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": "", 10 | "author": "", 11 | "license": "BSD", 12 | "dependencies": { 13 | "express-jwt": "~0.1.2", 14 | "request": "~2.34.0" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var expressJwt = require('express-jwt'); 2 | var validators = {}; 3 | var request = require('request'); 4 | 5 | function reload_validators (options) { 6 | request.get({ 7 | url: 'https://www.googleapis.com/oauth2/v1/certs', 8 | json: true 9 | }, function (err, resp, certs) { 10 | Object.keys(certs).forEach(function (kid) { 11 | validators[kid] = expressJwt({ 12 | audience: options.client_id, 13 | secret: certs[kid] 14 | }); 15 | }); 16 | }); 17 | } 18 | 19 | module.exports = function (options) { 20 | 21 | setTimeout(function () { 22 | reload_validators(options); 23 | }, 24 * 60 * 60); // since Google said that can change daily 24 | 25 | reload_validators(options); 26 | 27 | return function (req, res, next) { 28 | var auth_header = req.get('Authorization'); 29 | 30 | if (!auth_header || !auth_header.match(/^Bearer\s/)) { 31 | return res.send(401, 'missing authorization header'); 32 | } 33 | 34 | var token = auth_header.replace(/^Bearer\s/, ''); 35 | var header, kid; 36 | 37 | try { 38 | header = JSON.parse(Buffer(token.split('.')[0], 'base64').toString()); 39 | }catch(err) { 40 | return res.send(401, "can't parse the JWT's header"); 41 | } 42 | 43 | kid = header.kid; 44 | 45 | if (!kid) { 46 | return res.send(401, "missing kid in JWT's header"); 47 | } 48 | 49 | validators[kid](req, res, next); 50 | }; 51 | 52 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Use Google's JWTs to authenticate calls to your backend API. 2 | 3 | Google implements the standard OpenID Connect, after the authorization flow with `response_type=id_token` you will get a JWT in the client side of your application. You can use this JWT to authenticate calls to your api. 4 | 5 | This middleware validate three things __expiration__, __audience__ and __signature__. 6 | 7 | The signature is validated with the certs from https://www.googleapis.com/oauth2/v1/certs as stated in Google Docs [Validating an ID Token](https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken). These certs are downloaded when your application starts and every 24hs. 8 | 9 | If you want to validate JWT's from other sources (not google) use [express-jwt](http://github.com/auth0/express-jwt). 10 | 11 | ## Install 12 | 13 | ~~~ 14 | $ npm i connect-google-jwt 15 | ~~~ 16 | 17 | ## Usage 18 | 19 | In an express.js application: 20 | 21 | ~~~javascript 22 | var googleJWT = require('connect-google-jwt'); 23 | 24 | app.configure(function () { 25 | //middlewares 26 | this.use('/api', googleJWT({ 27 | client_id: 'your client id' 28 | })) 29 | }); 30 | 31 | app.get('/api/messages', function (req, res) { 32 | req.user // you have the decoded JWT here 33 | }); 34 | ~~~ 35 | 36 | ## License 37 | 38 | The MIT License (MIT) 39 | 40 | Copyright (c) 2014 AUTH10 LLC 41 | 42 | Permission is hereby granted, free of charge, to any person obtaining a copy 43 | of this software and associated documentation files (the "Software"), to deal 44 | in the Software without restriction, including without limitation the rights 45 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 46 | copies of the Software, and to permit persons to whom the Software is 47 | furnished to do so, subject to the following conditions: 48 | 49 | The above copyright notice and this permission notice shall be included in 50 | all copies or substantial portions of the Software. 51 | 52 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 53 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 54 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 55 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 56 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 57 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 58 | THE SOFTWARE. --------------------------------------------------------------------------------