如何在passport-twitter策略中使用会话变量req.user

时间:2023-01-20 00:00:02

As I can use req.user to get the logged in user in any of route by passing in:

因为我可以使用req.user通过传入来获取任何路由中的登录用户:

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?

我想允许用户使用除本地登录之外的Twitter登录,因此我在node.js API中有一个passport-twitter策略。如何使用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);
          }
        )
      }
    )
  );
};

2 个解决方案

#1


3  

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.

首先,我会检查您的系统中是否已有用户具有给定的Twitter个人资料ID。然后我会检查是否有用户具有相同的电子邮件地址。这意味着,用户已经注册了他的电子邮件。如果您的数据库中没有给定电子邮件地址或推特ID的用户,请创建一个新用户并将推特ID和电子邮件分配给此配置文件。

Dont forget to add the includeEmail options to the Strategy:

别忘了将includeEmail选项添加到策略中:

TwitterStrategy({
    consumerKey: "",
    consumerSecret: "",
    callbackURL: "http://localhost:3000"
    includeEmail: true, // <======= this
  }
)

The callback of the twitter oauth can look like that:

twitter oauth的回调可能如下所示:

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.

之后,您可以使用req.user访问下一个中间件中的用户配置文件。

#2


3  

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 * answer from a similar question pointed it out, but specifically for that strategy. The example below is copied from that answer.

Google Passport策略提供了将请求传递给验证回调的选项。它似乎完全符合我们的要求。这个来自类似问题的*回答指出了它,但专门针对该策略。以下示例是从该答案中复制的。

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.

在passport-twitter Github回购中的这条评论表明该选项也适用于该策略。我还没有确认,因为我没有在我自己的项目中将Twitter作为OAuth策略实现。

#1


3  

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.

首先,我会检查您的系统中是否已有用户具有给定的Twitter个人资料ID。然后我会检查是否有用户具有相同的电子邮件地址。这意味着,用户已经注册了他的电子邮件。如果您的数据库中没有给定电子邮件地址或推特ID的用户,请创建一个新用户并将推特ID和电子邮件分配给此配置文件。

Dont forget to add the includeEmail options to the Strategy:

别忘了将includeEmail选项添加到策略中:

TwitterStrategy({
    consumerKey: "",
    consumerSecret: "",
    callbackURL: "http://localhost:3000"
    includeEmail: true, // <======= this
  }
)

The callback of the twitter oauth can look like that:

twitter oauth的回调可能如下所示:

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.

之后,您可以使用req.user访问下一个中间件中的用户配置文件。

#2


3  

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 * answer from a similar question pointed it out, but specifically for that strategy. The example below is copied from that answer.

Google Passport策略提供了将请求传递给验证回调的选项。它似乎完全符合我们的要求。这个来自类似问题的*回答指出了它,但专门针对该策略。以下示例是从该答案中复制的。

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.

在passport-twitter Github回购中的这条评论表明该选项也适用于该策略。我还没有确认,因为我没有在我自己的项目中将Twitter作为OAuth策略实现。