user3056520
user3056520

Reputation: 21

Passport.js twitter authentication causing 500 error, req.session is undefined

I'm trying to set up sessions in a Node app using passport-twitter so I can persist user data, but from what I can tell, I cannot turn on the session support. Also, I made sure the callback function matches the application entry on Twitter Developers. The 500 error the program throws is:

500 Error: OAuthStrategy requires session support. Did you forget app.use(express.session(...))?**
    at Strategy.OAuthStrategy.authenticate (/Users/xxxxxxxx/web/Node/on/node_modules/passport-twitter/node_modules/passport-oauth1/lib/strategy.js:120:41)
    at Strategy.authenticate (/Users/xxxxxxxx/web/Node/on/node_modules/passport-twitter/lib/strategy.js:85:40)
    ....

When I check strategy.js at line 120, it says:

if (!req.session) { return this.error(new Error('OAuthStrategy requires session support. Did you forget app.use(express.session(...))?')); }

So, clearly req.session is undefined. However, I think I've done everything I need to to get the session support working. Here is most of my main server js file:

var express = require('express'),
app = express();

var http = require('http'),
https = require('https');

var mongodb = require('mongodb'),
mongoose = require('mongoose');

var passport = require('passport'),
TwitterStrategy = require('passport-twitter').Strategy,
imon = require('./imon'),
routes = require('./routes')(app),
user = require('./models/user'),
group = require('./models/group'),
song = require('./models/song'),
album = require('./models/album'),
activity_item = require('./models/activity_item');

app.set('env', 'development');

console.log("app.get('env') =", app.get('env'));
console.log(app.get('env') === 'development');

// development only
if (app.get('env') === 'development') {
    app.set('views', __dirname + '/views');
    app.use(express.logger('dev'));
    app.use(express.bodyParser());
    app.use(express.methodOverride());
    app.use(express.cookieParser('secret'));
    app.use(express.cookieSession());
    app.use(passport.initialize());
    app.use(passport.session());
    app.use(app.router);
    app.use(express.errorHandler());
}

// production only
if (app.get('env') === 'production') {
  // TODO
}


// all environments


mongoose.connect('mongodb://localhost/test');
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function callback () {
  console.log('Connected to DB');
});


passport.use(new TwitterStrategy({
    consumerKey: "0GOReNaXWXCTpf7OQgrg",
    consumerSecret: "0wA8yUBrXz3ivpTHcuBbKp3vGN2ODnOF7iFM9DB48Y",
    callbackURL: "http://127.0.0.1:8888/auth/twitter/callback"
  },
    function(token, tokenSecret, profile, done) {
        console.log("THis gets called?");
        function sanitizeImgURL(string){
            return string.replace("_normal", "");
        }

        console.log("profile: ", profile);
        process.nextTick(function(){
            User.find({account: {id: profile.id}}, function(err, user) {
                if(err){
                    return done(err);
                }
                if(!user){
                    return done(null, false, { message: 'Incorrect password.' });
                }
                else if(user){
                    done(null, user);
            }
            var newUser = new User(
                {account:
                    {provider: profile.provider,
                    id: profile.id},
                username: profile.username,
                displayName: profile.displayName,
                email: profile.email,
                image: sanitizeImgURL(profile._json.profile_image_url)
            });
            return done(null, newUser);
        });
    });
    }
));

passport.serializeUser(function(user, done) {
    console.log("SERIALIZE: ", user);
  done(null, user);
});

passport.deserializeUser(function(obj, done) {
    console.log("DESERIALIZE: ", obj);
  done(null, obj);
});


/**
 * Routes
 */

// Redirect the user to Twitter for authentication.  When complete, Twitter
// will redirect the user back to the application at
//   /auth/twitter/callback
app.get('/auth/twitter', passport.authenticate('twitter'));

// Twitter will redirect the user to this URL after approval.  Finish the
// authentication process by attempting to obtain an access token.  If
// access was granted, the user will be logged in.  Otherwise,
// authentication has failed.
app.get('/auth/twitter/callback',
  passport.authenticate('twitter', { successRedirect: '/static/index.html',
                                     failureRedirect: '/static/login.html' }));

... some routes ...

app.listen(8888);

Upvotes: 1

Views: 1999

Answers (1)

user3056520
user3056520

Reputation: 21

I figured it out; it was 2 things:

1.)connect-redis broke sessions, still don't know why, but removing it fixed my problem after I...

2.)... moved my require routes line, which takes the app object as an argument to after my app.use statements. It makes sense now, I was passing my app object to my routes before I configured it with things like, i dunno, SESSIONS.

Upvotes: 1

Related Questions