├── README.md ├── example ├── client.js ├── microservice.js └── server.js ├── index.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | # Authentic 2 | 3 | Authentication for microservices. This is collection of the following modules: 4 | 5 | * [authentic-server](https://github.com/davidguttman/authentic-server) 6 | * [authentic-service](https://github.com/davidguttman/authentic-service) 7 | * [authentic-client](https://github.com/davidguttman/authentic-client) 8 | 9 | ## What is it? ## 10 | 11 | Authentic is a collection of modules to help your various services authenticate a user. Put more concretely, Authentic does the following: 12 | 13 | * Allow your users to "sign up", "confirm", "log in", and "change password" with their email address and a chosen password (persisted to a db of your choice), and provide an authentication token ([JWT](http://jwt.io)) on successful log in. 14 | * Easily protect access to your microservice by decrypting a user's authentication token. 15 | * Help make requests from the browser to `authentic-server` for sign up/confirm/login/password reset, as well as automatically including the authentication token in requests to your microservices. 16 | 17 | There's also a more full [introduction to Authentic](http://dry.ly/authentic). 18 | 19 | ## Example ## 20 | 21 | Let's pretend you work at ScaleHaus (Uber meets Airbnb for lizards). You have a web app at `admin.scalehaus.io` (client-side SPA) that is an interface to various microservices (like `reporting.scalehaus.io`). You want to make sure that only employees with a `@scalehaus.io` email address have access to your app and microservices. Here's how you can do it: 22 | 23 | 1) Create an authentication server with [authentic-server](https://github.com/davidguttman/authentic-server) available at `auth.scalehaus.io`. 24 | 25 | 2) Add views to `admin.scalehaus.io` for signup/confirm/login/reset-password and use [authentic-client](https://github.com/davidguttman/authentic-client) for those actions and for requests to your microservices. 26 | 27 | 3) In your microservice(s), e.g. `reports.scalehaus.io`, use [authentic-service](https://github.com/davidguttman/authentic-service) to decrypt the authentication token provided in the request and verify the user's identity and that their email ends in `@scalehaus.io`. 28 | 29 | ## Installation ## 30 | 31 | It's best to install each module individually in the project that needs it. In theory, you could have a single project that needs to be the server, client, and service -- in that case feel free to `npm install --save authentic`. Otherwise use `npm install --save authentic-server`, `npm install --save authentic-service`, or `npm install --save authentic-client` depending on your project. 32 | 33 | ## In Action ## 34 | 35 | ### Authentic Server ### 36 | 37 | ```js 38 | var fs = require('fs') 39 | var http = require('http') 40 | var Authentic = require('authentic').server 41 | 42 | var auth = Authentic({ 43 | db: './userdb', 44 | publicKey: fs.readFileSync('/rsa-public.pem'), 45 | privateKey: fs.readFileSync('/rsa-private.pem'), 46 | sendEmail: function (email, cb) { 47 | // send the email however you'd like and call cb() 48 | } 49 | }) 50 | 51 | http.createServer(auth).listen(1337) 52 | console.log('Authentic Server listening on port', 1337) 53 | ``` 54 | 55 | ### Microservice ### 56 | 57 | Authentic provides a token decrypt function for easy use, but since everything is standard JWT, feel free to use your own (`authentic-server` exposes its public-key by default at `/auth/public-key`). 58 | 59 | ```js 60 | 61 | var http = require('http') 62 | var Authentic = require('authentic').service 63 | 64 | var auth = Authentic({ 65 | server: 'https://auth.scalehaus.io' 66 | }) 67 | 68 | http.createServer(function (req, res) { 69 | // Step 1: decrypt the token 70 | auth(req, res, function (err, authData) { 71 | if (err) return console.error(err) 72 | 73 | // Step 2: if we get an email and it's one we like, let them in! 74 | if (authData && authData.email.match(/@scalehaus\.io$/)) { 75 | res.writeHead(200) 76 | res.end('You\'re in!') 77 | 78 | // otherwise, keep them out! 79 | } else { 80 | res.writeHead(403) 81 | res.end('Nope.') 82 | } 83 | }) 84 | }).listen(1338) 85 | 86 | console.log('Protected microservice listening on port', 1338) 87 | 88 | ``` 89 | 90 | ### Client Login ### 91 | 92 | Authentic provides a HTTP JSON client for easy use, but since everything is standard JWT, feel free to use your own. 93 | 94 | ```js 95 | var Authentic = require('authentic').client 96 | 97 | var auth = Authentic({ 98 | server: 'https://auth.scalehaus.io' 99 | }) 100 | 101 | var creds = { 102 | email: 'chet@scalehaus.io', 103 | password: 'notswordfish' 104 | } 105 | 106 | // Step 1: log in 107 | auth.login(creds, function (err) { 108 | if (err) return console.error(err) 109 | 110 | // Step 2: make a JSON request with authentication 111 | var url = 'https://reporting.scalehaus.io/report' 112 | auth.get(url, function (err, data) { 113 | if (err) return console.error(err) 114 | 115 | // show that report 116 | console.log(data) 117 | }) 118 | }) 119 | 120 | ``` 121 | 122 | # License 123 | 124 | MIT 125 | -------------------------------------------------------------------------------- /example/client.js: -------------------------------------------------------------------------------- 1 | var Authentic = require('../').client 2 | 3 | var auth = Authentic({ 4 | server: 'https://auth.scalehaus.io' 5 | }) 6 | 7 | var creds = { 8 | email: 'chet@scalehaus.io', 9 | password: 'notswordfish' 10 | } 11 | 12 | // Step 1: log in 13 | auth.login(creds, function (err) { 14 | if (err) return console.error(err) 15 | 16 | // Step 2: make a JSON request with authentication 17 | var url = 'https://reporting.scalehaus.io/report' 18 | auth.get(url, function (err, data) { 19 | if (err) return console.error(err) 20 | 21 | // show that report 22 | console.log(data) 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /example/microservice.js: -------------------------------------------------------------------------------- 1 | var http = require('http') 2 | var Authentic = require('../').service 3 | 4 | var auth = Authentic({ 5 | server: 'https://auth.scalehaus.io' 6 | }) 7 | 8 | http.createServer(function (req, res) { 9 | // Step 1: decrypt the token 10 | auth(req, res, function (err, authData) { 11 | if (err) return console.error(err) 12 | 13 | // Step 2: if we get an email and it's one we like, let them in! 14 | if (authData && authData.email.match(/@scalehaus\.io$/)) { 15 | res.writeHead(200) 16 | res.end('You\'re in!') 17 | 18 | // otherwise, keep them out! 19 | } else { 20 | res.writeHead(403) 21 | res.end('Nope.') 22 | } 23 | }) 24 | }).listen(1338) 25 | 26 | console.log('Protected microservice listening on port', 1338) 27 | -------------------------------------------------------------------------------- /example/server.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs') 2 | var http = require('http') 3 | var Authentic = require('../').server 4 | 5 | var auth = Authentic({ 6 | db: __dirname + '/../db/', 7 | publicKey: fs.readFileSync(__dirname + '/rsa-public.pem'), 8 | privateKey: fs.readFileSync(__dirname + '/rsa-private.pem'), 9 | sendEmail: function (email, cb) { 10 | console.log(email) 11 | setImmediate(cb) 12 | } 13 | }) 14 | 15 | var server = http.createServer(function (req, res) { 16 | auth(req, res, next) 17 | 18 | function next (req, res) { 19 | // not an authentic route, send 404 or send to another route 20 | res.end('Not an authentic route =)') 21 | } 22 | }) 23 | 24 | server.listen(1337) 25 | console.log('Authentic enabled server listening on port', 1337) 26 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | server: require('authentic-server'), 3 | service: require('authentic-service'), 4 | client: require('authentic-client') 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "authentic", 3 | "version": "0.0.3", 4 | "description": "Authentication for microservices.", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "standard" 8 | }, 9 | "keywords": [], 10 | "author": "David Guttman (http://davidguttman.com/)", 11 | "license": "MIT", 12 | "directories": { 13 | "example": "example" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/davidguttman/authentic.git" 18 | }, 19 | "bugs": { 20 | "url": "https://github.com/davidguttman/authentic/issues" 21 | }, 22 | "homepage": "https://github.com/davidguttman/authentic#readme", 23 | "devDependencies": { 24 | "jsonist": "^1.3.0", 25 | "jsonwebtoken": "^5.4.1", 26 | "standard": "^5.3.1" 27 | }, 28 | "dependencies": { 29 | "authentic-client": "*", 30 | "authentic-server": "*", 31 | "authentic-service": "*" 32 | } 33 | } 34 | --------------------------------------------------------------------------------