Skip to content

Instantly share code, notes, and snippets.

@johnschimmel
Created April 7, 2012 11:26
Show Gist options
  • Save johnschimmel/2327766 to your computer and use it in GitHub Desktop.
Save johnschimmel/2327766 to your computer and use it in GitHub Desktop.
passport-foursquare setup with Mongoose
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