Last active
August 29, 2015 14:05
-
-
Save ryanvalentin/4318e300e43de28c6e4a to your computer and use it in GitHub Desktop.
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
// Disqus API public key | |
var apiPublic = 'YOUR_PUBLIC_KEY'; | |
// Disqus API secret key | |
var apiSecret = 'YOUR_SECRET_KEY'; | |
// Should match exactly what you've entered in your Disqus API application | |
var oAuthRedirectUri = 'https://MOBILE_SERVICE_NAME.azure-mobile.net/api/disqus_callback/'; | |
// Master key from your mobile service configuration | |
var azureMasterKey = 'AZURE_MASTER_KEY'; | |
exports.get = function(request, response) { | |
// Retrieve the code from the query | |
var code = request.query.code; | |
if (code !== undefined) { | |
// Code is set, so we know we're handling an OAuth callback request | |
// Make POST request for the temporary access token | |
var httpRequest = require('request'); | |
httpRequest({ | |
uri: 'https://disqus.com/api/oauth/2.0/access_token/', | |
method: 'POST', | |
form: { | |
grant_type: 'authorization_code', | |
client_id: apiPublic, | |
client_secret: apiSecret, | |
code: code, | |
redirect_uri: oAuthRedirectUri | |
} | |
}, function(httpError, httpResponse, httpBody) { | |
// Handle response from Disqus here | |
if (httpError || httpResponse.statusCode !== 200) { | |
// Error | |
console.error('Error retrieving access token: ' + httpBody); | |
response.send( | |
httpResponse.statusCode, | |
'Unable to connect to Disqus.' | |
); | |
} | |
else { | |
// Everything is good, respond with the access token | |
/* Body of request looks like this: | |
{ | |
"access_token": "c2d06abacfbb40179e47f62f06546ea9", | |
"refresh_token": "9182211bf2f746a4b5c5b1e3766443d6", | |
"expires_in": 2592000, | |
"username": "batman" | |
"user_id": "947103743" | |
} | |
*/ | |
var authorization = JSON.parse(httpBody); | |
// Get a reference to our user table | |
// TODO make sure you replace USER_TABLE_NAME with your actual table | |
var userTable = request.service.tables.getTable('USER_TABLE_NAME'); | |
userTable.where({ userId: authorization.user_id.toString() }).read({ | |
success: function (results) { | |
if (results.length === 0) { | |
// This user hasn't authenticated yet, so insert a new entry | |
userTable.insert(getUserEntry(authorization)); | |
} | |
else { | |
// User exists, so update the entry | |
var entry = getUserEntry(authorization); | |
entry.id = results[0].id; | |
userTable.update(entry); | |
} | |
}, | |
error: function (error) { | |
console.error('Error reading database', error); | |
response.send(500, error); | |
} | |
}); | |
var oneHundredYears = new Date().setUTCDate(new Date().getUTCDate() + 30000); | |
var token = generateToken(oneHundredYears, authorization.user_id, azureMasterKey); | |
response.send( | |
statusCodes.OK, | |
'Success! This is your Azure token: ' + | |
token | |
); | |
} | |
}); | |
} | |
else { | |
// No code in query, so send the user to the authorize URL | |
var redirectUri = 'https://disqus.com/api/oauth/2.0/authorize/' + | |
'?client_id=' + apiPublic + | |
'&scope=read,write' + | |
'&response_type=code'; | |
response.redirect(redirectUri); | |
} | |
}; | |
function getUserEntry(authorization) { | |
return { | |
accessToken: authorization.access_token, | |
refreshToken: authorization.refresh_token, | |
userId: authorization.user_id, | |
username: authorization.username, | |
expires: Math.round((new Date().getTime() / 1000) + authorization.expires_in) | |
}; | |
} | |
// Generates a token recognized by Azure mobile services as an authenticated user | |
function generateToken(expiryDate, userId, masterKey) { | |
var crypto = require('crypto'); | |
function base64(input) { | |
return new Buffer(input, 'utf8').toString('base64'); | |
} | |
function urlFriendly(b64) { | |
return b64.replace(/\+/g, '-').replace(/\//g, '_').replace(new RegExp('=', 'g'), ''); | |
} | |
function signature(input) { | |
var key = crypto.createHash('sha256').update(masterKey + 'JWTSig').digest('binary'); | |
var str = crypto.createHmac('sha256', key).update(input).digest('base64'); | |
return urlFriendly(str); | |
} | |
var s1 = '{"alg":"HS256","typ":"JWT","kid":0}'; | |
var j2 = { | |
'exp': expiryDate.valueOf() / 1000, | |
'iss': 'urn:microsoft:windows-azure:zumo', | |
'ver': 1, | |
'aud': 'Disqus', | |
'uid': userId | |
}; | |
var s2 = JSON.stringify(j2); | |
var b1 = urlFriendly(base64(s1)); | |
var b2 = urlFriendly(base64(s2)); | |
var b3 = signature(b1 + "." + b2); | |
return [b1,b2,b3].join('.'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment