简体   繁体   中英

github Oauth for node.js/express application private email

I am using passport-github strategy for my express application. This works fine when the user has set a public email address, but does not work if there is no email!

if process.env.GITHUB_ID? and process.env.GITHUB_SEC?   
  passport.use(new GitHubStrategy
    clientID: process.env.GITHUB_ID
    clientSecret: process.env.GITHUB_SEC
    callbackURL: url+"/social/githubcallback"
  , (accessToken, refreshToken, profile, done) ->
    console.log("arguments in github strategy");
    console.log("profile.emails", profile.emails);
    console.log(profile.emails[0].value);
    console.log(arguments);
    emails = []
    for mail in profile.emails
      emails.push mail.value
    if !emails[0]
      emails[0] = profile.id
    User.findOneAndUpdate(
      "email": 
        $in: emails
    ,  
      $addToSet:
        "provider": profile.provider
    , (err, user) ->
      console.log("user arguments at github strategy");
      console.log(arguments);
      console.log("email at passport callback:", profile.emails);
      if err? then return done err, null,
        message: 'authorizationfailed',
        data: '.',
        message2: 'tryagain'
      unless user
        Name = ''
        if profile.displayName?
          Name = profile.displayName
        else 
          Name = profile.username
        User.create(
          "email": emails[0]
          "provider": [profile.provider]
          "name": Name
          "surname": ""
          "active": true
          "groups": "member"
        , (err,newUser)->

          if err? then return done err, null, 
            message: 'authorizationfailed',
            data: '.',
            message2: 'tryagain'
          done null, newUser,
            message: 'authorizationsuccess'
            data: '.'
            message2: 'welcome'
        )
      else
        done null, user,
          message: 'authorizationsuccess'
          data: '.'
          message2: 'welcome'
    )
  )

so in my mongodb i get the user as:

{
    "tokenExpires" : 1374052875909,
    "tokenString" : "Ll551X6Y2z-vOKCl8vTIjB5do9qxkJHL7ObRyovxlmvxZzQV7AXYgvl4424F1CZH",
    "email" : "85080",
    "_id" : ObjectId("51e5108b562c19d921000001"),
    "provider" : [
        "github"
    ],
    "lockUntil" : 0,
    "loginAttempts" : 0,
    "groups" : "member",
    "surname" : "",
    "name" : "Norman Khine",
    "active" : true,
    "password" : "$2a$10$j3KDCQ55AZROm1ggaJU5GeOaWafSzggkINl1Sy1mpLSrWtaIJTFxC",
    "__v" : 0
}

so if there is no email provided i am using the profile.id

what i am trying to achieve is that in my application i have several federated login options plus the local strategy, if a user with the same email logs in, then the mongodb record is updated so i get a record like:

{
    "__v" : 0,
    "_id" : ObjectId("51e507f7dbaac20000000001"),
    "active" : true,
    "email" : "norman@khine.net",
    "groups" : "member",
    "lockUntil" : 0,
    "loginAttempts" : 0,
    "name" : "Norman",
    "password" : "$2a$10$BRGbsMQof9TtF62SKAAeYOEVp0mjcupuICsrXcTukYImgnrrsQJ6a",
    "provider" : [
        "persona",
        "google",
        "local"
    ],
    "surname" : "Khine",
    "tokenExpires" : 1374050774162,
    "tokenString" : "hkTVcPWwWnPeXPPm5u28v6nsHbrbp-VXpJWScTSGHD7TFt3Q2HcWjNntqUOv3WFx"
}

here is the user.coffee that writes the user to the mongodb:

# Register new user
UserSchema.statics.register = (user, cb) ->
  self = new this(user)
  user.email = sanitize(user.email.toLowerCase().trim()).xss()
  validator.check(user.email, messages.VALIDATE_EMAIL).isEmail()
  errors = validator.getErrors()
  if errors.length
    errorString = errors.join("<br>")
    return cb(errorString)
    console.log "Registration form failed with " + errors
    #go to the signup page
    return cb(errorString, null)
  else
    @findOne
      email: user.email
    , (err, existingUser) ->
      return cb(err)  if err
      return cb("user-exists")  if existingUser
      self.save (err) ->
        return cb(err) if err
        cb null, self

what would be the correct way to signup users from github who do not have a public email setup?

any advice much appreciated

You need to add a scope ( "user:email" ) when declaring the GithubStrategy. Then once you've been authorized, use the access token you get to visit https://api.github.com/user/emails?access_token={your access token} ... you should get a response along the lines ["user@domain.com"] ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM