Last active
June 16, 2021 09:34
-
-
Save hramos/63dd9ea0c05086a57a5c to your computer and use it in GitHub Desktop.
Revisions
-
hramos revised this gist
Oct 21, 2014 . 1 changed file with 22 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,22 @@ Parse Cloud Module for managing Facebook Login server side using Express. To log in, visit https://YOUR_SUBDOMAIN.parseapp.com/login. Installation ============ Move `main.js` and `app.js` into your `cloud/` folder in Cloud Code if it's a new project. If you're already using Express, update your `app.js` accordingly. If you already have a Parse Hosting app set up, but you're not using Express yet, add the following to your `main.js: require('cloud/app.js'); Update `app.js` to use your actual [Facebook App](https://developers.facebook.com/apps)'s client id and app secret. This module will create a `TokenRequest` class in your Parse app. If you have client-side class creation turned off, you will need to manually create this class. Note: This is a work in progress ================================ This example code is provided for demonstration purposes and no support is implied for the use of this user module at this time. -
hramos revised this gist
Oct 21, 2014 . 3 changed files with 42 additions and 0 deletions.There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,34 @@ var express = require('express'); var parseExpressHttpsRedirect = require('parse-express-https-redirect'); var parseExpressCookieSession = require('parse-express-cookie-session'); var parseFacebookUserSession = require('cloud/parse-facebook-user-session'); var app = express(); app.set('views', 'cloud/views'); app.set('view engine', 'jade'); app.use(express.bodyParser()); app.use(parseExpressHttpsRedirect()); app.use(express.cookieParser('foobarbazqux')); app.use(parseExpressCookieSession({ fetchUser: true })); app.use(parseFacebookUserSession({ clientId: 'YOUR_FACEBOOK_APP_CLIENT_ID', appSecret: 'YOUR_FACEBOOK_APP_SECRET', redirectUri: '/login', })); app.get('/', function(req, res) { var user = Parse.User.current(); res.render('hello', { message: 'Congrats, you are logged in, ' + user.get('name') + '!' }); }); app.get('/logout', function(req, res) { Parse.User.logOut(); res.render('hello', { message: 'You are now logged out!' }); }); app.listen(); 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1 @@ require('cloud/app.js'); 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,7 @@ doctype 5 html head title Sample App body h1 Hello World p= message -
hramos created this gist
Oct 21, 2014 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,167 @@ var moment = require('moment'); var querystring = require('querystring'); /** * A middleware module for logging in a Parse.User using Facebook in express. * * Params includes the following: * clientId (required): The client id of the Facebook App. * appSecret (required): The app secret of the Facebook App. * redirectUri (optional): The path on this server to use for handling the * redirect callback from Facebook. If this is omitted, it defaults to * /login. */ var parseFacebookUserSession = function(params) { if (!params.clientId || !params.appSecret) { throw "You must specify a Facebook clientId and appSecret."; } var relativeRedirectUri = params.redirectUri || "/login"; /** * Returns the absolute url of the redirect path for this request. */ var getAbsoluteRedirectUri = function(req) { return 'https://' + req.host + relativeRedirectUri; }; /** * Starts the Facebook login OAuth process. */ var beginLogin = function(req, res) { console.log("Starting Facebook login..."); Parse.Promise.as().then(function() { // Make a request object. Its objectId will be our XSRF token. console.log("Creating TokenRequest..."); var url = 'https://' + req.host + req.path; var request = new Parse.Object("TokenRequest"); return request.save({ url: url, ACL: new Parse.ACL() }); }).then(function(request) { console.log("Redirecting for Facebook OAuth."); // Put the XSRF token into a cookie so that we can match it later. res.cookie("requestId", request.id); // Redirect the user to start the Facebook OAuth flow. var url = 'https://www.facebook.com/dialog/oauth?'; url = url + querystring.stringify({ client_id: params.clientId, redirect_uri: getAbsoluteRedirectUri(req), state: request.id }); res.redirect(302, url); }); }; /** * Handles the last stage of the Facebook login OAuth redirect. */ var endLogin = function(req, res) { console.log("Handling request callback for Facebook login..."); if (req.query.state !== req.cookies.requestId) { console.log("Request failed XSRF validation."); res.send(500, "Bad Request"); return; } var url = 'https://graph.facebook.com/oauth/access_token?'; url = url + querystring.stringify({ client_id: params.clientId, redirect_uri: getAbsoluteRedirectUri(req), client_secret: params.appSecret, code: req.query.code }); var accessToken = null; var expires = null; var facebookData = null; Parse.Promise.as().then(function() { console.log("Fetching access token..."); return Parse.Cloud.httpRequest({ url: url }); }).then(function(response) { console.log("Fetching user data from Facebook..."); var data = querystring.parse(response.text); accessToken = data.access_token; expires = data.expires; var url = 'https://graph.facebook.com/me?'; url = url + querystring.stringify({ access_token: accessToken }); return Parse.Cloud.httpRequest({ url: url }); }).then(function(response) { console.log("Logging into Parse with Facebook token..."); facebookData = response.data; var expiration = moment().add('seconds', expires).format( "YYYY-MM-DDTHH:mm:ss.SSS\\Z"); return Parse.FacebookUtils.logIn({ id: response.data.id, access_token: accessToken, expiration_date: expiration }); }).then(function(response) { console.log("Becoming Parse user..."); return Parse.User.become(response.sessionToken); }).then(function(user) { console.log("Saving Facebook data for user..."); user.set("name", facebookData.name); return user.save(); }).then(function(user) { console.log("Fetching TokenRequest for " + req.query.state + "..."); var request = new Parse.Object("TokenRequest"); request.id = req.query.state; return request.fetch({ useMasterKey: true }); }).then(function(request) { console.log("Deleting used TokenRequest..."); // Let's delete this request so that no one can reuse the token. var url = request.get("url"); return request.destroy({ useMasterKey: true }).then(function() { return url; }); }).then(function(url) { console.log("Success!"); res.redirect(302, url); }, function(error) { console.log("Failed! " + JSON.stringify(error)); res.send(500, error); }); }; /** * The actual middleware method. */ return function(req, res, next) { // If the user is already logged in, there's nothing to do. if (Parse.User.current()) { return next(); } // If this is the Facebook login redirect URL, then handle the code. var absoluteRedirectUri = 'https://' + req.host + relativeRedirectUri; if (req.path === relativeRedirectUri) { endLogin(req, res); } else { beginLogin(req, res); } }; }; module.exports = parseFacebookUserSession;