Accounts.createUser没有用户名,密码和电子邮件

时间:2016-12-30 06:41:58

标签: facebook reactjs meteor meteor-accounts

我的应用程序是使用React构建的,它与Meteor完全分开。我使用Asteroid与Meteor接口,Meteor仅用作后端。我已经在前端手动创建了Facebook登录按钮,并希望将从Facebook获取的数据传递给Accounts.createUser。这个方法要求提供两个不可用的参数,因为我已将其格式化为:

const data = {
    services: {
        facebook: fb
    },
    profile: {
        first_name: fb.first_name,
        last_name: fb.last_name,
    }
}

我已经创建了一个方法,但是我没有使用适当的令牌或Meteor所需的指示器来记录用户:

getLoginByExternalService(options) {
    if (Meteor.userId()) throw new Meteor.Error('400',`Please logout ${Meteor.userId()}`);
    const email = options.services.facebook.email
    const facebookId = options.services.facebook.id
    const user = {services: {}}
    user.services = options.services
    const users = Meteor.users.find({"services.facebook.id": facebookId}).fetch();

    if (!users.length) {
        const userId = Accounts.insertUserDoc(options, user)
        if (Meteor.isServer)
            this.setUserId(userId)
        else
            Meteor.setUserId(userId)
        return userId
    } else {

        if (Meteor.isServer)
            this.setUserId(users[0]._id)

        if (Meteor.isClient)
            Meteor.setUserId(userId)

        return {users, userId: Meteor.userId()}
    }
}

如何正确登录用户?

1 个答案:

答案 0 :(得分:1)

好的,我已经得到了答案。我不必格式化Facebook响应的数据返回。所以这里是后端的实现

/^\w.*$/gm

所以在前端的某个地方

getLoginByExternalService(resp) {
    if (Meteor.userId()) Meteor.logout(Meteor.userId()) //who knows?
    const accessToken = resp.accessToken
    const identity = getIdentity(accessToken)
    const profilePicture = getProfilePicture(accessToken)
    const serviceData = {
        accessToken: accessToken,
        expiresAt: (+new Date) + (1000 * resp.expiresIn)
    }
    const whitelisted = ['id', 'email', 'name', 'first_name', 'last_name', 'link', 'username', 'gender', 'locale', 'age_range']
    const fields = _.pick(identity, whitelisted)
    const options = {profile: {}}
    const profileFields = _.pick(identity, getProfileFields())
    //creating the token and adding to the user
    const stampedToken = Accounts._generateStampedLoginToken()
    //hashing is something added with Meteor 0.7.x, 
    //you don't need to do hashing in previous versions
    const hashStampedToken = Accounts._hashStampedToken(stampedToken)
    let ref = null
    _.extend(serviceData, fields)
    _.extend(options.profile, profileFields)
    options.profile.avatar = profilePicture

    try {
      ref = Accounts.updateOrCreateUserFromExternalService("facebook", serviceData, options);
    } catch (e) {
      if (e.reason === "Email already exists.") {
         const existingUser = Meteor.users.findOne({ 'emails.address': identity.email })
         if ( existingUser ) {
           if ( identity.verified ) {
              Meteor.users.update({ _id: existingUser._id }, { $set: { 'services.facebook': serviceData }})
              ref = { userId: existingUser._id }
              console.log(`Merged facebook identity with existing local user ${existingUser._id}`);
           } else {
              throw Meteor.Error(403, "Refusing to merge unverified facebook identity with existing user")
           }
         }
     } else {
        throw Meteor.Error(e.error, e.reason)
     }
  }

  Meteor.users.update(ref.userId, {$push: {'services.resume.loginTokens': hashStampedToken}})

  return {id: ref.userId, token: stampedToken.token}
}