Last active
February 13, 2018 21:44
-
-
Save FoxxMD/207fc6f6545d07741537 to your computer and use it in GitHub Desktop.
A snippet of an express app that authenticates users using oauth and serves apis through a proxy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var express = require("express"); | |
var bodyParser = require("body-parser"); | |
var httpProxy = require('http-proxy'); | |
var url = require('url'); | |
var sessions = require("client-sessions"); | |
// configure session cookie | |
// sessions encrypts the cookie so even though the client has physical access | |
// the information it holds is not revealed (client's access token) | |
app.use(sessions({ | |
cookieName: 'auth', | |
secret: currentConfig.clientSecret, //environmental variable | |
duration: 48 * 60 * 60 * 1000, | |
cookie: { | |
httpOnly: false | |
} | |
})); | |
// body parser for use with login | |
// Use this so you can conform to the oauth spec (IE use form-data with POST) | |
var bparser = bodyParser.urlencoded({extended: false}); | |
//rest library | |
var rest = require('restler'); | |
//parse body of login request for username/pass | |
app.post('/login', bparser, function (req, res) { | |
console.log('****** App Login ******'); | |
console.log('App is logging in.'); | |
//console.log('Request data: '); | |
//console.log(req.body); | |
rest.post(currentConfig.API_URL + '/oauth/access_token', { | |
data: { | |
username: req.body.username, | |
password: req.body.password, | |
client_id: currentConfig.clientId, //get clientId from environmental variables | |
client_secret: currentConfig.clientSecret, //get secret from environmental variables | |
grant_type: 'password' | |
} | |
}).on('complete', function (data, response) { | |
console.log('Got auth response!'); | |
//console.log(data); | |
res.status(response.statusCode); | |
if(response.statusCode !== 200) { // oauth server didn't accept our auth attempt | |
console.log('Response was not OK: ' + response.statusCode); | |
res.json(data); //return errors from api | |
} | |
else { //successfully authenticated with oauth server | |
req.auth.accessToken = data.access_token; // get access token and add it to session cookie (remember it's encrypted now!) | |
console.log('Access token set in cookie: ' + req.auth.accessToken); | |
//console.log('Full cookie'); | |
//console.log(req.auth); | |
console.log('***********'); | |
res.send(); | |
} | |
}); | |
}); | |
app.get('/logout', function (req, res) { | |
req.auth.reset(); //remove access token from client | |
res.status(200); | |
res.send(); | |
}); | |
//api proxy | |
// the client (the js app) makes requests as if it is communicating with the real api server | |
// so all the proxy is doing is decrypting the cookie sent by the client and attaching it to the request | |
app.all("/api/*", function (req, res) { | |
var newUrl = req.url.substr(4); //removing /api/ from url path because api server doesn't use this prefix in the url | |
console.log('***** Api Proxy *****'); | |
console.log('Api Requested at path: ' + newUrl); | |
// console.log('Auth cookie: '); | |
// console.log(req.auth); | |
if (req.auth && req.auth.accessToken) { //if session cookie exists and we can find the accessToken | |
//console.log('Found access token: ' + req.auth.accessToken); | |
req.headers['Authorization'] = 'Bearer ' + req.auth.accessToken; //intercept api request and add authorization | |
//console.log('Auth header set: ' + req.headers['Authorization']); | |
req.url = newUrl; | |
req.headers['uierror'] = true; | |
proxy.web(req, res, {target: currentConfig.API_URL}); //send api request through proxy | |
} | |
else { //if missing access token or cookie inform the client | |
console.log('Missing access token!'); | |
body = { | |
code: 407, | |
message: 'Missing client auth cookie.' | |
}; | |
res.status(401).json(body); | |
} | |
console.log('**********'); | |
}); | |
proxy.on('proxyRes', function (proxyRes, req, res) { | |
if(proxyRes.statusCode == 500){ | |
console.log('Target Server Error!'); | |
if(res.body){ | |
console.log(res.body); | |
} | |
} | |
//console.log('RAW Response from the target', JSON.stringify(proxyRes.headers, true, 2)); | |
}); | |
proxy.on('error', function(err, req, res) { | |
res.end(); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment