Created
October 2, 2015 10:09
-
-
Save stefek99/bafee8492128c63aa572 to your computer and use it in GitHub Desktop.
Authentication
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
exports.exchangeTokens = function(code) { | |
var defer = q.defer(); | |
var requestURL = "https://www.googleapis.com/oauth2/v3/token"; | |
var post_data = { | |
code : code, | |
client_id : google_client_id, | |
client_secret : google_client_secret, | |
redirect_uri : 'postmessage', | |
grant_type : "authorization_code", | |
}; | |
// https://github.com/request/request#forms | |
request.post(requestURL, { form: post_data }, function(error, response, body) { | |
// console.log("ERROR: " + error + "\n\n"); | |
// console.log("BODY: " + body + "\n\n"); | |
defer.resolve(JSON.parse(body)); | |
}); | |
return defer.promise; | |
}; | |
exports.refreshToken = function(refresh_token) { | |
var defer = q.defer(); | |
var requestURL = "https://www.googleapis.com/oauth2/v3/token"; | |
var post_data = { | |
refresh_token : refresh_token, | |
client_id : google_client_id, | |
client_secret : google_client_secret, | |
grant_type : "refresh_token" | |
}; | |
request.post(requestURL, { form: post_data }, function(error, response, body) { | |
//console.log("ERROR: " + error + "\n\n"); | |
//console.log("BODY: " + body + "\n\n"); | |
defer.resolve(JSON.parse(body)); | |
}); | |
return defer.promise; | |
}; | |
exports.checkToken = function(access_token) { | |
var defer = q.defer(); | |
var requestURL = "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" + access_token; | |
request.get(requestURL, function(error, response, body) { | |
// console.log("ERROR: " + error + "\n\n"); // error is always null, it's the error property of the body response that is set | |
// console.log("BODY: " + body + "\n\n"); | |
// TRYING TO DEBUG | |
try { | |
defer.resolve(JSON.parse(body)); // google returns it as string | |
} catch(exception) { | |
console.log("GOOGLE CHECK TOKEN PARSE FAIL"); | |
console.log(body); | |
defer.reject(null); | |
} | |
}); | |
return defer.promise; | |
}; | |
exports.userInfo = function(access_token) { | |
var defer = q.defer(); | |
var requestURL = "https://www.googleapis.com/oauth2/v1/userinfo?access_token=" + access_token; | |
request.get(requestURL, function(error, response, body) { | |
// console.log("ERROR: " + error + "\n\n"); // error is always null, it's the error property of the body response that is set | |
// console.log("BODY: " + body + "\n\n"); | |
defer.resolve(JSON.parse(body)); | |
}); | |
return defer.promise; | |
}; |
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 verifyToken = function (req, res, next) { | |
var getAccessTokens = function(email) { | |
var defer = q.defer(); | |
ref.child("users/email:" + email.replace(".", "(dot)") + "/access_tokens").once("value", function(snap) { | |
var access_tokens = snap.val(); | |
defer.resolve(access_tokens); | |
}); | |
return defer.promise; | |
}; | |
var email = req.query.email; | |
var access_token = req.query.access_token; | |
var skip = req.query.skip; | |
if (skip) { // sometimes - when debugging - I want to hit api method without worrying about access_token | |
next(); | |
return; | |
} | |
if (req.url === "/syncFinished") { // allowing callback from ContextIO that obviously does not have authentication | |
next(); | |
return; | |
} | |
if (! access_token || access_token === "undefined") { // sometimes `access_token` gets serialised as string | |
res.send({message : "No access_token. Returning."}); | |
return; | |
} | |
if (! email || email === "undefined") { // sometimes `email` gets serialised as string | |
res.send({message : "No email. Returning."}); | |
return; | |
} | |
google.checkToken(access_token).then(function(response) { | |
if (! response.error) { | |
if (response.email !== email) { | |
res.send({message : "This token does not belong to this email. Weird. Are you a hacker?"}); | |
return; | |
} | |
next(); | |
getAccessTokens(email).then(function(access_tokens) { | |
if (_.contains(access_tokens, access_token) === false) { | |
console.log("This access_token have not been seen. Adding to the list..."); | |
ref.child("users/email:" + email.replace(".", "(dot)") + "/access_tokens").push(access_token); | |
} | |
}); | |
} else { | |
// Current access_token is invalid. But maybe it's only 3600 TTL... | |
// Checking if this token was valid and if yes - refreshing and returning new value to the client | |
getAccessTokens(email).then(function(access_tokens){ | |
if (_.contains(access_tokens, req.query.access_token)) { | |
console.log("This access_token was previously valid. Refreshing..."); | |
ref.child("users/email:" + email.replace(".", "(dot)") + "/refresh_token").once("value", function(snap) { | |
var refresh_token = snap.val(); | |
google.refreshToken(refresh_token).then(function(result) { | |
console.log("Refreshed. " + JSON.stringify(result) + " Carrying on..."); | |
res.append('new_access_token', result.access_token); // adding to the headers so the client can update | |
req.query.access_token = result.access_token; // updatin req, so further down the line there are no errors | |
ref.child("users/email:" + req.query.email.replace(".", "(dot)") + "/access_tokens").push(result.access_token); | |
next(); | |
}); | |
}); | |
} else { | |
res.send({message : "Wrong access_token. Tried matching with the previous one but still doesn't work."}); | |
} | |
}); | |
} | |
}); | |
}; | |
app.use(verifyToken); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment