gpt4 book ai didi

oauth - 使用 Meteor Accounts 包链接多个服务

转载 作者:行者123 更新时间:2023-12-03 13:27:00 24 4
gpt4 key购买 nike

所以 Meteor 有这个很棒的 Accounts 包,它允许通过密码或其他服务轻松登录。但是,我目前正在创建一个需要多种服务的 Web 服务(facebook/twitter/等)。这里的链接:How to add External Service logins to an already existing account in Meteor?通过创建重复帐户并仅合并数据来建议“破解”,但这对我来说似乎很不满意。
所以我的问题是:
1) 有没有更优雅的方式来使用 Accounts-xxx 包来创建一个用户但附加了多个服务?
2)如果没有,我可以使用现在分离的 oauth 包将 token 添加到一个用户。例如,如果稍后手动“附加”了 github token ,Accounts.loginWithGithub 以后还会发现手动合并的帐户吗?
谢谢你的帮助。

最佳答案

解决了!

我通过逆向工程解决了这个问题 accounts-oauth-X包!处理所有边缘情况的最佳解决方案是让一个故事用于登录,另一个用于显式关联。以下是用 literate coffeescript 编写的解决方案。

前:

确保您拥有所需的软件包:

meteor add google
meteor add facebook
meteor add oauth

多服务登录方法:

如果帐户具有相同的电子邮件,则会自动加入帐户。最适合用于登录,因为它很健壮。但是,这对于显式关联并不好,因为如果电子邮件地址不同,那么它将不起作用。 (手动合并将注销用户并强制您重新登录)。对于显式关联帐户,即使它有不同的电子邮件,请参阅下面的解决方案。

服务器端代码:
Accounts.onCreateUser (options, user) ->
user.city = null
user.networks = []
user.attending =[]
user.profile ?= {}

如果用户通过 oauth 服务注册,我们需要执行额外的逻辑,以便
我们可以标准化姓名和电子邮件的位置。
  if user.services?
service = _.keys(user.services)[0]

检查是否有任何现有帐户已经拥有与
服务。如果是这样,只需将用户信息纳入其中。
    email = user.services[service].email
if email?
oldUser = Meteor.users.findOne({"emails.address": email})

确保旧帐户具有所需的服务对象。
      if oldUser?
oldUser.services ?= {}
if service == "google" or service == "facebook"

将新的服务 key 合并到我们的旧用户中。我们还会检查是否有新的
电子邮件添加到我们的用户。然后从数据库中删除旧用户,然后
再次返回以直接再次创建它。假定的新用户
被创建被丢弃。
          oldUser.services[service] = user.services[service]
Meteor.users.remove(oldUser._id)
user = oldUser

否则,只需照常创建用户,标准化电子邮件和姓名字段。
      else
if service == "google" or service == "facebook"
if user.services[service].email?
user.emails = [{address: user.services[service].email, verified: true}]
else
throw new Meteor.Error(500, "#{service} account has no email attached")
user.profile.name = user.services[service].name

return user

显式关联的方法:

这会将服务添加到用户记录上的服务散列中,就像它是由内置散列系统创建的一样。代码需要在客户端(获取服务 oauth token )和部分服务器端(进行进一步的 API 调用以获取用户数据并将其与用户记录相关联)

客户端代码:

此功能是向我们的帐户添加功能的入口点。
addUserService = (service) ->

如果他们选择电子邮件,我们需要使用 Meteor 内置的电子邮件验证系统。
  if service == "email"

else
switch service

对于标准 oauth 服务,我们在客户端请求凭据,并且
然后将它们传递给服务器以进行进一步的 API 调用以收集
必要的信息并将该信息添加到我们的帐户中。
      when "facebook"
Facebook.requestCredential(
requestPermissions: ["email", "user_friends", "manage_notifications"],
, (token) ->
Meteor.call "userAddOauthCredentials", token, Meteor.userId(), service, (err, resp) ->
if err?
Meteor.userError.throwError(err.reason)
)
when "google"
Google.requestCredential
requestPermissions: ["email", "https://www.googleapis.com/auth/calendar"]
requestOfflineToken: true,
, (token) ->
Meteor.call "userAddOauthCredentials", token, Meteor.userId(), service, (err, resp) ->
if err?
Meteor.userError.throwError(err.reason)

我们只需要设置一个简单的绑定(bind)将它们粘合在一起。
Template.userAddServices.events
"click button": (e) ->
e.preventDefault()
service = $(event.target).data("service")
addUserService(service)

服务器端代码:

这里我们定义了与用户模型相关的服务器端方法。
Meteor.methods

这从客户端传递了数据,客户端获取了访问 token
已经。使用 token 发现有关用户的其余信息
在那项服务上。然后它会检查该帐户是否已经注册,
如果没有 - 将其添加到当前帐户。
  userAddOauthCredentials: (token, userId, service) ->
switch service
when "facebook"
data = Facebook.retrieveCredential(token).serviceData
when "google"
data = Google.retrieveCredential(token).serviceData

selector = "services.#{service}.id"
oldUser = Meteor.users.findOne({selector: data.id})
if oldUser?
throw new Meteor.Error(500, "This #{service} account has already" +
"been assigned to another user.")

updateSelector = "services.#{service}"
Meteor.users.update(userId, {$set: {updateSelector: data }})

我们也可以通过此帐户发送电子邮件。如果它还没有在
当前用户,我们可以抓取它并添加它。
    if not _.contains(Meteor.user().emails, data.email)
Meteor.users.update(userId, {$push: {"emails": {address: data.email, verified: true} }})

关于oauth - 使用 Meteor Accounts 包链接多个服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18358007/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com