0

I'm using nodejs, express 4 and everyauth for social network authentication. I'm having some problem where I click Accept from Google and and redirects back to my / I get

_http_outgoing.js:335

throw new Error('Can\'t set headers after they are sent.');

I'm using electrolyte as a DI as well but I don't think that would be an issue. Here's my code

index.js

var express = require('express'),
    http = require('http'),
    bootable = require('bootable');

var app = bootable(express());

app.phase(bootable.initializers('etc/init', app));

app.phase(bootable.routes(__dirname + '/routes.js', app));

app.phase(function listen(done) {
    http.createServer(app).listen(process.env.PORT || 3000, function(err) {
        if (err) { return done(err); }

        var addr = this.address();
        console.log('server listening on http://' + addr.address + ':' + addr.port);
        done();
    });
});

module.exports = app;

routes.js

var IoC = require('electrolyte');

module.exports = function routes() {

    this.get('/', IoC.create('handlers/homepage'));
    this.get('/api/foursquare', IoC.create('handlers/api/foursquare')); 
    //this.get('/auth/google/callback', IoC.create('handlers/auth/google_auth_callback'));
}

handlers/homepage

exports = module.exports = function() {
    function render(req, res, next) {
        res.render('index');    
    };

    return [render];
};

google.js

var everyauth = require('everyauth'),
    GoogleUser = require('../../app/models/google_user'),
    mongoose = require('../../app/db/mongo');

require('dotenv').load();

module.exports = function() {

    everyauth.google
        .appId(process.env.GOOGLE_CLIENT_ID)
        .appSecret(process.env.GOOGLE_CLIENT_SECRET)
        .scope('https://www.googleapis.com/auth/plus.login') // What you want access to
        .handleAuthCallbackError( function (req, res) {
            // If a user denies your app, Google will redirect the user to
            // /auth/facebook/callback?error=access_denied
            // This configurable route handler defines how you want to respond to
            // that.
            // If you do not configure this, everyauth renders a default fallback
            // view notifying the user that their authentication failed and why.
        })
    .findOrCreateUser( function (session, accessToken, accessTokenExtra, googleUserMetadata) {
        console.log('come back from google');
        console.log(session);
        // find or create user logic goes here
        // Return a user or Promise that promises a user
        // Promises are created via
        //     var promise = this.Promise();
        /*
        var googleUser = new GoogleUser(mongoose);
        var johndoe = new googleUser({
            accessToken: 'accessToken',
            expires: new Date(),
            refreshToken: 'refreshToken',
            email: 'john@doe.com',
            createdAt: new Date()
        });

        var promise = this.Promise();
        promise.resolve(johndoe);

        return promise;
        */
    }).redirectPath('/');
};

mongo.js

var mongoose = require('mongoose')

require('dotenv').load();

var uristring = process.env.MONGOLAB_URI;
mongoose.connect(uristring, function (err, res) {
    if (err) { 
        console.log ('ERROR connecting to: ' + uristring + '. ' + err);
    } else {
        console.log ('Succeeded connected to: ' + uristring);
    }
});

exports = module.exports = mongoose 
mscdex
  • 104,356
  • 15
  • 192
  • 153
toy
  • 11,711
  • 24
  • 93
  • 176
  • add the code of handleAuthCallbackError and findOrCreateUser. you will get `Can't set headers after they are sent.` error if the response is edited after response.send is called. – Vishnu Jul 25 '15 at 15:56
  • So I just have to remove one of them? – toy Jul 25 '15 at 16:15

1 Answers1

0

You will get Can't set headers after they are sent. if your code is like this

  if (err) {
    res.send(err);
  }
  else if(!user) {
    res.send(info);
  }
  res.send(user);

In the above code, if user is undefined it sends the info as response and it again comes to next statement i.e res.send(user);. So it cannot set headers to the response which is already sent.

You can prevent this by

if (err) {
    res.send(err);
  }
  else if(!user) {
    res.send(info);
  }
  else {
    res.send(user);
  }

or

if (err) {
    return res.send(err);
  }
  else if(!user) {
    return res.send(info);
  }

  return res.send(user);
Vishnu
  • 11,614
  • 6
  • 51
  • 90
  • You can understand better from this link http://stackoverflow.com/questions/23165569/res-send-how-to-exit-after – Vishnu Jul 25 '15 at 17:04