Last active
March 29, 2020 15:07
-
-
Save claudioacioli/9eaca7ccef917e2e830890ccd7236964 to your computer and use it in GitHub Desktop.
RefreshToken
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 request = require("sync-request"); | |
var url = require("url"); | |
var qs = require("qs"); | |
var querystring = require('querystring'); | |
var cons = require('consolidate'); | |
var randomstring = require("randomstring"); | |
var __ = require('underscore'); | |
__.string = require('underscore.string'); | |
var app = express(); | |
app.engine('html', cons.underscore); | |
app.set('view engine', 'html'); | |
app.set('views', 'files/client'); | |
// authorization server information | |
var authServer = { | |
authorizationEndpoint: 'http://localhost:9001/authorize', | |
tokenEndpoint: 'http://localhost:9001/token' | |
}; | |
// client information | |
var client = { | |
"client_id": "oauth-client-1", | |
"client_secret": "oauth-client-secret-1", | |
"redirect_uris": ["http://localhost:9000/callback"], | |
"scope": "foo" | |
}; | |
var protectedResource = 'http://localhost:9002/resource'; | |
var state = null; | |
var access_token = '987tghjkiu6trfghjuytrghj'; | |
var scope = null; | |
var refresh_token = 'j2r3oj32r23rmasd98uhjrk2o3i'; | |
app.get('/', function (req, res) { | |
res.render('index', {access_token: access_token, scope: scope, refresh_token: refresh_token}); | |
}); | |
app.get('/authorize', function(req, res){ | |
access_token = null; | |
scope = null; | |
state = randomstring.generate(); | |
var authorizeUrl = buildUrl(authServer.authorizationEndpoint, { | |
response_type: 'code', | |
scope: client.scope, | |
client_id: client.client_id, | |
redirect_uri: client.redirect_uris[0], | |
state: state | |
}); | |
console.log("redirect", authorizeUrl); | |
res.redirect(authorizeUrl); | |
}); | |
app.get('/callback', function(req, res){ | |
if (req.query.error) { | |
// it's an error response, act accordingly | |
res.render('error', {error: req.query.error}); | |
return; | |
} | |
var resState = req.query.state; | |
if (resState != state) { | |
console.log('State DOES NOT MATCH: expected %s got %s', state, resState); | |
res.render('error', {error: 'State value did not match'}); | |
return; | |
} | |
var code = req.query.code; | |
var form_data = qs.stringify({ | |
grant_type: 'authorization_code', | |
code: code, | |
redirect_uri: client.redirect_uris[0] | |
}); | |
var headers = { | |
'Content-Type': 'application/x-www-form-urlencoded', | |
'Authorization': 'Basic ' + new Buffer(querystring.escape(client.client_id) + ':' + querystring.escape(client.client_secret)).toString('base64') | |
}; | |
var tokRes = request('POST', authServer.tokenEndpoint, | |
{ | |
body: form_data, | |
headers: headers | |
} | |
); | |
console.log('Requesting access token for code %s',code); | |
if (tokRes.statusCode >= 200 && tokRes.statusCode < 300) { | |
var body = JSON.parse(tokRes.getBody()); | |
access_token = body.access_token; | |
console.log('Got access token: %s', access_token); | |
if (body.refresh_token) { | |
refresh_token = body.refresh_token; | |
console.log('Got refresh token: %s', refresh_token); | |
} | |
scope = body.scope; | |
console.log('Got scope: %s', scope); | |
res.render('index', {access_token: access_token, scope: scope, refresh_token: refresh_token}); | |
} else { | |
res.render('error', {error: 'Unable to fetch access token, server response: ' + tokRes.statusCode}) | |
} | |
}); | |
app.get('/fetch_resource', function(req, res) { | |
console.log('Making request with access token %s', access_token); | |
var headers = { | |
'Authorization': 'Bearer ' + access_token, | |
'Content-Type': 'application/x-www-form-urlencoded' | |
}; | |
var resource = request('POST', protectedResource, | |
{headers: headers} | |
); | |
if (resource.statusCode >= 200 && resource.statusCode < 300) { | |
var body = JSON.parse(resource.getBody()); | |
res.render('data', {resource: body}); | |
return; | |
} else { | |
access_token = null; | |
if (refresh_token) { | |
refreshAccessToken(req, res); | |
return; | |
} else { | |
res.render('error', {error: resource.statusCode}); | |
return; | |
} | |
} | |
}); | |
var refreshAccessToken = function(req, res) { | |
var form_data = qs.stringify({ | |
grant_type: 'refresh_token', | |
refresh_token: refresh_token | |
}); | |
var headers = { | |
'Content-Type': 'application/x-www-form-urlencoded', | |
'Authorization': 'Basic ' + encodeClientCredentials(client.client_id, client.client_secret) | |
}; | |
console.log('Refreshing token %s', refresh_token); | |
var tokRes = request('POST', authServer.tokenEndpoint, { | |
body: form_data, | |
headers: headers | |
}); | |
if (tokRes.statusCode >= 200 && tokRes.statusCode < 300) { | |
var body = JSON.parse(tokRes.getBody()); | |
access_token = body.access_token; | |
console.log('Got access token: %s', access_token); | |
if (body.refresh_token) { | |
refresh_token = body.refresh_token; | |
console.log('Got refresh token: %s', refresh_token); | |
} | |
scope = body.scope; | |
console.log('Got scope: %s', scope); | |
// try again | |
res.redirect('/fetch_resource'); | |
return; | |
} else { | |
console.log('No refresh token, asking the user to get a new access token'); | |
// tell the user to get a new access token | |
refresh_token = null; | |
res.render('error', {error: 'Unable to refresh token.'}); | |
return; | |
} | |
}; | |
var buildUrl = function(base, options, hash) { | |
var newUrl = url.parse(base, true); | |
delete newUrl.search; | |
if (!newUrl.query) { | |
newUrl.query = {}; | |
} | |
__.each(options, function(value, key, list) { | |
newUrl.query[key] = value; | |
}); | |
if (hash) { | |
newUrl.hash = hash; | |
} | |
return url.format(newUrl); | |
}; | |
var encodeClientCredentials = function(clientId, clientSecret) { | |
return new Buffer(querystring.escape(clientId) + ':' + querystring.escape(clientSecret)).toString('base64'); | |
}; | |
app.use('/', express.static('files/client')); | |
var server = app.listen(9000, 'localhost', function () { | |
var host = server.address().address; | |
var port = server.address().port; | |
console.log('OAuth Client is listening at http://%s:%s', host, port); | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment