Created
April 7, 2012 11:26
-
-
Save johnschimmel/2327766 to your computer and use it in GitHub Desktop.
passport-foursquare setup with Mongoose
This file contains 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 ejs = require('ejs'); //embedded javascript template engine | |
var app = express.createServer(express.logger()); | |
var mongoose = require('mongoose'); // include Mongoose MongoDB library | |
var schema = mongoose.Schema; | |
var requestURL = require('request'); | |
//include passport-foursquare | |
var passport = require('passport') | |
, util = require('util') | |
, FoursquareStrategy = require('passport-foursquare').Strategy; | |
var FOURSQUARE_CLIENT_ID = "your foursquare client id"; | |
var FOURSQUARE_CLIENT_SECRET = "your foursquare client secret"; | |
/************ DATABASE CONFIGURATION **********/ | |
app.db = mongoose.connect(process.env.MONGOLAB_URI); //connect to the mongolabs database - local server uses .env file | |
// Include models.js - this file includes the database schema and defines the models used | |
require('./models').configureSchema(schema, mongoose); | |
// Define your DB Model variables | |
var BlogPost = mongoose.model('BlogPost'); | |
var Comment = mongoose.model('Comment'); | |
var User = mongoose.model('User'); | |
/************* END DATABASE CONFIGURATION *********/ | |
/****** PASSPORT FOURSQUARE CONFIG ********/ | |
// Passport session setup. | |
// To support persistent login sessions, Passport needs to be able to | |
// serialize users into and deserialize users out of the session. Typically, | |
// this will be as simple as storing the user ID when serializing, and finding | |
// the user by ID when deserializing. However, since this example does not | |
// have a database of user records, the complete Foursquare profile is | |
// serialized and deserialized. | |
passport.serializeUser(function(user, done) { | |
done(null, user); | |
}); | |
passport.deserializeUser(function(obj, done) { | |
User.findById(obj._id, function (err, user) { | |
done(err, user); | |
}); | |
}); | |
// Use the FoursquareStrategy within Passport. | |
// Strategies in Passport require a `verify` function, which accept | |
// credentials (in this case, an accessToken, refreshToken, and Foursquare | |
// profile), and invoke a callback with a user object. | |
passport.use(new FoursquareStrategy({ | |
clientID: FOURSQUARE_CLIENT_ID, | |
clientSecret: FOURSQUARE_CLIENT_SECRET, | |
callbackURL: "http://127.0.0.1:5000/auth/foursquare/callback" | |
}, | |
function(accessToken, refreshToken, profile, done) { | |
// asynchronous verification, for effect... | |
process.nextTick(function () { | |
console.log("inside callback"); | |
//console.log(profile); | |
User.findOne({foursquareID:profile.id}, function(err, user){ | |
if (user) { | |
console.log("***********************************"); | |
console.log("found existing user"); | |
console.log(user); | |
return done(null, user); | |
} else { | |
//create user with your own schema | |
user = new User({ | |
foursquareID : profile.id, | |
name : profile.name, | |
email : profile.emails[0].value | |
}) | |
user.save(function(err) { | |
console.log("***********************************"); | |
console.log("created new user"); | |
console.log(user); | |
if (err == null) { | |
return done(null, user); // Return the new user you created | |
} | |
}) | |
} | |
}) | |
// To keep the example simple, the user's Foursquare profile is returned | |
// to represent the logged-in user. In a typical application, you would | |
// want to associate the Foursquare account with a user record in your | |
// database, and return that user instead. | |
//return done(null, profile); | |
}); | |
} | |
)); | |
// Simple route middleware to ensure user is authenticated. | |
// Use this route middleware on any resource that needs to be protected. If | |
// the request is authenticated (typically via a persistent login session), | |
// the request will proceed. Otherwise, the user will be redirected to the | |
// login page. | |
function ensureAuthenticated(req, res, next) { | |
if (req.isAuthenticated()) { return next(); } | |
res.redirect('/login') | |
} | |
/*********** SERVER CONFIGURATION *****************/ | |
app.configure(function() { | |
/********************************************************************************* | |
Configure the template engine | |
We will use EJS (Embedded JavaScript) https://github.com/visionmedia/ejs | |
Using templates keeps your logic and code separate from your HTML. | |
We will render the html templates as needed by passing in the necessary data. | |
*********************************************************************************/ | |
app.set('view engine','ejs'); // use the EJS node module | |
app.set('views',__dirname+ '/views'); // use /views as template directory | |
app.set('view options',{layout:true}); // use /views/layout.html to manage your main header/footer wrapping template | |
app.set( "jsonp callback", true ); | |
app.register('html',require('ejs')); //use .html files in /views | |
/****************************************************************** | |
The /static folder will hold all css, js and image assets. | |
These files are static meaning they will not be used by | |
NodeJS directly. | |
In your html template you will reference these assets | |
as yourdomain.heroku.com/img/cats.gif or yourdomain.heroku.com/js/script.js | |
******************************************************************/ | |
app.use(express.static(__dirname + '/static')); | |
//handle cookies | |
app.use(express.cookieParser()); | |
//parse any http form post | |
app.use(express.bodyParser()); | |
app.use(express.methodOverride()); | |
app.use(express.session({ secret: 'keyboard cat' })); | |
// Initialize Passport! Also use passport.session() middleware, to support | |
// persistent login sessions (recommended). | |
app.use(passport.initialize()); | |
app.use(passport.session()); | |
/**** Turn on some debugging tools ****/ | |
app.use(express.logger()); | |
app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); | |
}); | |
/*********** END SERVER CONFIGURATION *****************/ | |
app.get('/', function(req, res){ | |
res.render('index.html', { user: req.user }); | |
}); | |
app.get('/account', ensureAuthenticated, function(req, res){ | |
res.render('account.html', { user: req.user }); | |
}); | |
app.get('/login', function(req, res){ | |
res.render('login.html', { user: req.user }); | |
}); | |
// end of main page | |
// GET /auth/foursquare | |
// Use passport.authenticate() as route middleware to authenticate the | |
// request. The first step in Foursquare authentication will involve | |
// redirecting the user to foursquare.com. After authorization, Foursquare | |
// will redirect the user back to this application at /auth/foursquare/callback | |
app.get('/auth/foursquare', | |
passport.authenticate('foursquare'), | |
function(req, res){ | |
// The request will be redirected to Foursquare for authentication, so this | |
// function will not be called. | |
}); | |
// GET /auth/foursquare/callback | |
// Use passport.authenticate() as route middleware to authenticate the | |
// request. If authentication fails, the user will be redirected back to the | |
// login page. Otherwise, the primary route function function will be called, | |
// which, in this example, will redirect the user to the home page. | |
app.get('/auth/foursquare/callback', | |
passport.authenticate('foursquare', { failureRedirect: '/login' }), | |
function(req, res) { | |
res.redirect('/account'); | |
}); | |
// Make server turn on and listen at defined PORT (or port 3000 if is not defined) | |
var port = process.env.PORT || 3000; | |
app.listen(port, function() { | |
console.log('Listening on ' + port); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment