Reputation: 207
I just want to link twitter account after there is still user.
Firstly i have a router.js like that
// GET Registration Page
router.get('/signup', function(req, res){
res.render('register',{noty: req.flash('message')});
});
// Handle Registration POST
router.post('/signup', passport.authenticate('signup', {
successRedirect: '/connect_twitter',
failureRedirect: '/signup',
failureFlash : true
}));
/* GET Twitter Auth*/
router.get('/login/twitter', passport.authenticate('twitter'));
router.get('/login/twitter/return',
passport.authenticate('twitter', { failureRedirect: '/' }),
function(req, res) {
res.redirect('/home');
});
if its success, i redirected "/connect_twitter"
with req.user != null
, that is current user. In the "/connect_twitter"
a redirect twitter with a button.
When twitter return user's tokens, i use this strategy
passport.use(new TwitterStrategy({
consumerKey: config.twitter.consumer_key,
consumerSecret: config.twitter.consumer_secret,
callbackURL: config.tw_callback
},
function(token, tokenSecret, profile, cb) {
// In this example, the user's Twitter profile is supplied as the user
// record. In a production-quality application, the Twitter profile should
console.log(profile);
findOrCreateUser = function(){
// find a user in Mongo with provided username
User.findOne({'tw_user_id': profile.id}, function(err, user) {
// In case of any error, return using the done method
if (err){
return cb(err);
}
// already exists
if (user) {
user.tw_token = token;
user.tw_token_secret = tokenSecret;
user.save(function(err){
if (err) {
throw err;
}
console.log("User Updating successfull !");
})
return cb(null, user);
} else {
// create the user
var newUser = new User();
// set the user's local credentials
newUser.password = createHash(token);
newUser.username = profile.username;
newUser.email = null;
newUser.tw_token = token;
newUser.tw_user_id = profile.id;
newUser.tw_token_secret = tokenSecret;
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log('User Registration succesful');
return cb(null, newUser);
});
}
});
};
process.nextTick(findOrCreateUser);
}));
The problem is how to access current_user or anything about the current user in this function function(token, tokenSecret, profile, cb)
?
As i think, If i access that, i linked current user with these tokens.
Or
Is there better (any) way to link twitter with the current user ?
Thanks in advance..
Upvotes: 4
Views: 737
Reputation: 207
In the passportjs docs
Association in Verify Callback
One downside to the approach described above is that it requires two instances of the same strategy and supporting routes.
To avoid this, set the strategy's
passReqToCallback
option totrue
. With this option enabled, req will be passed as the first argument to the verify callback.
passport.use(new TwitterStrategy({
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackURL: "http://www.example.com/auth/twitter/callback",
passReqToCallback: true
},
function(req, token, tokenSecret, profile, done) {
if (!req.user) {
// Not logged-in. Authenticate based on Twitter account.
} else {
// Logged in. Associate Twitter account with user. Preserve the login
// state by supplying the existing user after association.
// return done(null, req.user);
}
}
));
With
req
passed as an argument, the verify callback can use the state of the request to tailor the authentication process, handling both authentication and authorization using a single strategy instance and set of routes. For example, if a user is already logged in, the newly "connected" account can be associated. Any additional application-specific properties set onreq
, includingreq.session
, can be used as well.
By the way, you can handle with the current user and its data to link any social strategy including Twitter.
Upvotes: 4
Reputation: 15550
You can do that in 2 ways:
Instead of trying to get req.user
inside Twitter Strategy, you can get user email fetched from twitter response and match it with user with same email inside database. Normally, you cannot get email directly from Twitter API, you need to fill request form here to get elevated access. After request accepted, you will be able to get email from Twitter API.
After twitter login, you can save user twitter profile information inside a temp table and redirect a page like /user/do_login?twitter_profile_id=<user_twitter_profile_id_fetched_from_twitter_response>
. When you redirect to /user/do_login
you will be able to access req.user
and also you will have user profile id. In this action, you can grab user profile info from temp table and merge it with req.user
. By the way, I assume that, you are using stored session.
Upvotes: 0