Skip to content

Instantly share code, notes, and snippets.

@ryanvalentin
Last active August 29, 2015 14:05
Show Gist options
  • Save ryanvalentin/4318e300e43de28c6e4a to your computer and use it in GitHub Desktop.
Save ryanvalentin/4318e300e43de28c6e4a to your computer and use it in GitHub Desktop.
// 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