passport-twitter icon indicating copy to clipboard operation
passport-twitter copied to clipboard

unable to get user email.

Open Adetona opened this issue 6 years ago • 8 comments

I've requested permission from apps.twitter.com and the authentication process is working successfully but twitter is not returning the user's email. Please check my code if there is something wrong with what I'm doing. Thanks

var passport = require('passport');
var LocalStrategy    = require('passport-local').Strategy;
var TwitterStrategy  = require('passport-twitter').Strategy;

// load up the user model
var User       = require('../app/models/user');

// load the auth variables
var configAuth = require('./auth');

module.exports = function(passport) {

    // used to serialize the user for the session
    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });

    // used to deserialize the user
    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            done(err, user);
        });
    });

    // code for login (use('local-login', new LocalStategy))
    // code for signup (use('local-signup', new LocalStategy))
    // code for facebook (use('facebook', new FacebookStrategy))

    // =========================================================================
    // TWITTER =================================================================
    // =========================================================================
    passport.use(new TwitterStrategy({

        consumerKey     : configAuth.twitterAuth.consumerKey,
        consumerSecret  : configAuth.twitterAuth.consumerSecret,
        callbackURL     : configAuth.twitterAuth.callbackURL,
        userProfileURL: "https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true",
         passReqToCallback : true,

    },
    function(token, tokenSecret, profile, done) {

        // make the code asynchronous
    // User.findOne won't fire until we have all our data back from Twitter
        process.nextTick(function() {

            User.findOne({ 'twitter.id' : profile.id }, function(err, user) {

                // if there is an error, stop everything and return that
                // ie an error connecting to the database
                if (err)
                    return done(err);

                // if the user is found then log them in
                if (user) {
                    return done(null, user); // user found, return that user
                } else {
                    // if there is no user, create them
                    var newUser                 = new User();

                    // set all of the user data that we need
                    newUser.twitter.id          = profile.id;
                    newUser.twitter.token       = token;
                    newUser.twitter.username    = profile.username;
                    newUser.twitter.displayName = profile.displayName;
                    newUser.twitter.email       = profile.email; 

                    // save our user into the database
                    newUser.save(function(err) {
                        if (err)
                            throw err;
                        return done(null, newUser);
                    });
                }
            });

    });

    }));

};

Adetona avatar Jan 25 '18 10:01 Adetona

same here

ahromyak avatar Mar 26 '18 13:03 ahromyak

I can confirm this issue. Any status on a fix?

elaine-jackson avatar Apr 13 '18 17:04 elaine-jackson

@ahromyak @nsuchy Yes, there is now a fix.

Simply pass profile.emails[0].value to the variable you want to save your email to.

Example:

newUser.twitter.email = profile.emails[0].value

I'm sorry it took me so long to give a response.

Adetona avatar May 09 '18 22:05 Adetona

Twitter can return the email but if you don't explicitly ask for it it will not. By reading the source code of this Strategy, here is how you should ask for the email:

TwitterStrategy({
    consumerKey: configAuth.twitterAuth.consumerKey,
    consumerSecret : configAuth.twitterAuth.consumerSecret,
    callbackURL: configAuth.twitterAuth.callbackURL,
    includeEmail: true, // <======= this
    // also other options
  },
  // ...
)

As written here https://github.com/jaredhanson/passport-twitter/blob/master/lib/strategy.js#L119

It will return the email of the user in his profile in the field email as you expected.

jebarjonet avatar Jul 14 '18 21:07 jebarjonet

Also try going to the developer console, the "Permissions" tab, click "Edit", check off "Request email address from users" under "Additional permissions" and click "Save".

adamzerner avatar Jul 01 '20 20:07 adamzerner

consumerKey: process.env.CONSUMER_KEY,
consumerSecret: process.env.CONSUMER_SECRET,
includeEmail: true,
callbackURL: '/dashboard/auth/callback',
proxy: true

This is my strategy, and here, 99% of the time I receive an email address, but not 1% of the time. How can I solve this?

bigansh avatar Apr 12 '21 13:04 bigansh

I tried both includeEmail and userProfileURL with include_email parameter set to true and they still don't work. includeEmail doesn't return profile.emails, and userProfileURL with a include_email query will throw 500 Internal Server Error

Edit: I do have permission enabled on twitter API and regenerated the key and secret

Mokin711 avatar Jun 18 '21 21:06 Mokin711

Twitter can return the email but if you don't explicitly ask for it it will not. By reading the source code of this Strategy, here is how you should ask for the email:

TwitterStrategy({
    consumerKey: configAuth.twitterAuth.consumerKey,
    consumerSecret : configAuth.twitterAuth.consumerSecret,
    callbackURL: configAuth.twitterAuth.callbackURL,
    includeEmail: true, // <======= this
    // also other options
  },
  // ...
)

As written here https://github.com/jaredhanson/passport-twitter/blob/master/lib/strategy.js#L119

It will return the email of the user in his profile in the field email as you expected.

Hi we are running into this problem right now, and this solution includeEmail: true does not work. Could you take a look at our stackoverflow? https://stackoverflow.com/questions/75180779/node-js-passport-twitter-unable-to-get-user-email-in-passport-twitter-authentic

leongaban avatar Jan 21 '23 05:01 leongaban