Reputation: 119
As I can use req.user
to get the logged in user in any of route by passing in:
passport.authenticate("jwt", { session: false })
I want to allow the user to sign in with twitter other than local login, so I have a passport-twitter strategy in node.js API. How can I access locally logged in user with req.user?
module.exports = passport => {
passport.use(
new Strategy({
consumerKey: "",
consumerSecret: "",
callbackURL: "http://localhost:3000"
},
function(token, tokenSecret, profile, cb) {
Profile.findOne({
user: req.user._id
}).then(
userdetail => {
userdetail.twuser = profile._json.screen_name;
userdetail.token = token;
userdetail.tokenSecret = tokenSecret;
userdetail.save().then();
return cb(null, profile);
}
)
}
)
);
};
Upvotes: 7
Views: 849
Reputation: 1190
The Google Passport strategy provides an option to pass the request to the verify
callback. It seems to do exactly what we are looking for. This stackoverflow answer from a similar question pointed it out, but specifically for that strategy. The example below is copied from that answer.
passport.use(new GoogleStrategy({
clientID: process.env.GOOGLE_CLIENTID,
clientSecret: process.env.GOOGLE_CLIENTSECRET,
callbackURL: "http://127.0.0.1:7777/google/callback",
passReqToCallback: true
},
// google will send back the token and profile
function(req, token, refreshToken, profile, done) {
// req.user is the currently logged-in user
…
})
This comment in the passport-twitter
Github repo suggests that the option is available to that strategy as well. I have not yet confirmed, as I have not implemented Twitter as an OAuth strategy in my own project.
Upvotes: 3
Reputation: 138
First of all, i would check if there is already a user in your system with the given twitter profile id. Then i would check if there is a user with the same email address. That means, that the user already signed up with his email. If there is no user with the given email address or twitter id in your database, create a new one and assign the twitter id and email to this profile.
Dont forget to add the includeEmail options to the Strategy:
TwitterStrategy({
consumerKey: "",
consumerSecret: "",
callbackURL: "http://localhost:3000"
includeEmail: true, // <======= this
}
)
The callback of the twitter oauth can look like that:
async (token, tokenSecret, profile, cb) => {
const existingProfileWithTwitterId = await Profile.findOne({ twid: profile.id }
if (existingProfileWithTwitterId) {
return callback(null, profile)
}
const existingProfileWithEmail = await Profile.findOne({ email: profile.emails[0].value }
if (existingProfileWithEmail) {
existingProfileWithEmail.twid = profile.id
// Add some more stuff from twitter profile if you want
await existingProfileWithEmail.save()
return callback(null, existingProfileWithEmail)
}
// Create a new Profile
const profile = new Profile({
twid: profile.id,
// add some more properties
})
return callback(null, profile)
})
After that, you can access to user profile in the next middlewares with req.user.
Upvotes: 3