Node.js — Getting oAuth Up and Running Using Express.js, Railway.js and Mongoose
Let's get started
If you're interested in how to incorporate this without using railwayjs, see this other article instead.
This is assuming you already have a working railwayjs project working. If not:
sudo npm install railway -g
rw i blog && cd blog
npm install -l
rw g crud post title content
# make sure mongodb is running
rw s 3000
open http://localhost:3000/posts
If you need to install mongodb, it's simple. In Ubuntu, you can just apt-get install mongodb, or in osx, brew install mongodb;. If you need to install homebrew for OSX, /usr/bin/ruby -e "$(curl -fsSL https://raw.github.com/gist/323731)".
Setting up the environment
First things first, change your package.json to include mongoose-auth.
{ "name": "railwayjs project"
, "version": "0.0.1"
, "engines": ["node >= 0.4.0"]
, "main": "server.js"
, "dependencies":
{ "jade-ext": ">= 0"
, "jade": ">= 0"
, "express": ">= 2.2.2"
, "connect": ">= 1.4.2"
, "railway": ">= 0.1.6"
, "yaml": ">= 0.1.2"
, "coffee-script": ">= 1.1.1"
, "mime": ">= 1.2.2"
, "qs": ">= 0.1.0"
, "mongoose": ">= 1.3.6"
, "mongodb": ">= 0.9.4-5"
, "connect-mongodb": ">= 0.3.0"
, "mongoose-auth": ">= 0.0.2"
}
, "scripts":
{ "test": "nodeunit test/*/*"
}
}
Next, we're going to change our config/environment.js to look like the following:
var express = require('express');
var mongooseAuth = require('mongoose-auth');
require('./mongoose_oauth');
app.configure(function() {
var cwd;
cwd = process.cwd();
app.set('views', cwd + '/app/views');
app.set('view engine', 'jade');
app.use(express.static(cwd + '/public', {
maxAge: 86400000
}));
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
secret: 'secret'
}));
// MAKE SURE THIS IS COMMENTED OUT, otherwise it will produce errors that are mostly nonsensical
//app.use(app.router)
app.use(express.methodOverride());
app.use(mongooseAuth.middleware());
});
mongooseAuth.helpExpress(app);
Notice the use of the require statement, require('./mongoose_oauth');, this files contents are here and look like:
var mongoose = require('mongoose')
, Schema = mongoose.Schema;
var conf = require('./oauth_providers');
var UserSchema = new Schema({})
, User;
mongooseAuth = require('mongoose-auth');
UserSchema.plugin(mongooseAuth, {
everymodule: {
everyauth: {
User: function() {
return User;
}
}
},
facebook: {
everyauth: {
myHostname: 'http://local.host:3001',
appId: conf.fb.appId,
appSecret: conf.fb.appSecret,
redirectPath: '/'
}
},
twitter: {
everyauth: {
myHostname: 'http://local.host:3001',
consumerKey: conf.twit.consumerKey,
consumerSecret: conf.twit.consumerSecret,
redirectPath: '/'
}
},
github: {
everyauth: {
myHostname: 'http://local.host:3001',
appId: conf.github.appId,
appSecret: conf.github.appSecret,
redirectPath: '/'
}
}
});
User = mongoose.model('User', UserSchema);
module.exports["User"] = mongoose.model("User");
module.exports["User"].modelName = "User";
Also notice, the configuration file, config/oauth_providers.js, this looks like:
module.exports = {
fb: {
appId: '111565172259433',
appSecret: '85f7e0a0cc804886180b887c1f04a3c1'
},
twit: {
consumerKey: 'JLCGyLzuOK1BjnKPKGyQ',
consumerSecret: 'GNqKfPqtzOcsCtFbGTMqinoATHvBcy1nzCTimeA9M0'
},
github: {
appId: '11932f2b6d05d2a5fa18',
appSecret: '2603d1bc663b74d6732500c1e9ad05b0f4013593'
},
instagram: {
clientId: 'be147b077ddf49368d6fb5cf3112b9e0',
clientSecret: 'b65ad83daed242c0aa059ffae42feddd'
},
};
NOTE: these keypairs really shouldn't be made public, but they exist in the mongoose-auth repo, so you can test using them. This also assumes you have something setup in /etc/hosts to map local.host to 127.0.0.1, example: 127.0.0.1 local.host
The views
Now, if you were to run your app, rw s 3000, and go to http://local.host:3000/auth/twitter, you would find, after logging in to twitter, it redirects you back to the homepage, as per the mongoose_oauth.js config. But how do you know if you're actually logged in, and the user is being stored in the session?
Well, we have to update a view to contain the following information:
- var items = ["facebook", "github", "twitter", "instagram"]
- if (!everyauth.loggedIn)
h2 Not Authenticated
each item in items
a(href='/auth/' + item)
span Connect with <span style="text-transform: capitalize">!{item}</span><br />
- else
h2 Authenticated
#user-id Logged in with `user.id` #{user.id} - aka `everyauth.user.id` #{everyauth.user.id}
- if (everyauth.facebook)
h3 Facebook User Data
p= JSON.stringify(everyauth.facebook.user)
- if (everyauth.twitter)
h3 Twitter User Data
p= JSON.stringify(everyauth.twitter.user)
- if (everyauth.github)
h3 GitHub User Data
p= JSON.stringify(everyauth.github.user)
- if (everyauth.instagram)
h3 Instagram User Data
p= JSON.stringify(everyauth.instagram.user)
h3
a(href='/logout') Logout
And Done!
Now you should see various metadata depending on how you're logged in. All the files above can be found in this gist.