Skip to content

Instantly share code, notes, and snippets.

@FoxxMD
Last active February 13, 2018 21:44
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FoxxMD/207fc6f6545d07741537 to your computer and use it in GitHub Desktop.
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
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