如何使用 Google 用户预填充我的 Rails 4 应用程序?

How do I pre-populate my Rails 4 application with a Google user?

我正在使用 Rails 4.2.5 和“omniauth-google-oauth2”gem。在我的应用程序中,用户能够登录的唯一方式是通过他们的 Google 或 Facebook 登录。我想要的是用初始用户预填充我的应用程序,我(电子邮件 = 'davea@gmail.com”),具有管理员角色。以编程方式执行此操作会很好,这样当我将其推广到其他环境时,我可以使用相同的代码。

我的角色 table(通过 db/seeds.rb)拥有角色

Admin
User

我的 app/model/user.rb 文件有

def self.from_omniauth(auth)
  where(auth.slice(:provider, :uid)).first_or_initialize.tap do |user|
    user.provider = auth.provider
    user.uid = auth.uid
    user.name = auth.info.name
    user.oauth_token = auth.credentials.token
    user.oauth_expires_at = Time.at(auth.credentials.expires_at)
    user.save!
  end
end

不过,我不确定如何做我想做的事,因此希望得到一些建议。

您必须 运行 通过您的控制器通过 seed.rb 文件发出请求才能执行 OAuth2 流程。

由于您很可能需要从 GUI 输入凭据或 select 您的 google 帐户,我建议 运行 在您的 seed.rb 中输入一个系统命令将浏览器打开到您的授权操作的 url 的文件。

# Mac:
system("open <url_to_authorize_action>")

如果这需要序列化,紧随其后,添加一个 while 循环,每 N 次阈值检查一次 DB,以查看该用户是否被授权。

while <user_not_authorized> do
    sleep <N seconds>
end

您可以将其推广到多个开发环境,但显然不能推广到生产环境。

现在假设您有 Google uid。只需从您的种子创建一个用户,例如:

user = User.new(
  provider: "google",
  uid: "your-google-id",
  email: "davea@gmail.com",
  name: "Your name"
)
user.roles << admin_role # Replace this line with your role assignment
user.save # Perhaps use save(validate: false) if there're validations for other fields

这样,当您使用 Google 登录时,omniauth 逻辑应该能够找到种子用户,这意味着您将能够充当管理员。

请注意,这假设您不需要 Google oauth 令牌来执行任何进一步的操作,因为您没有保存它,并且从您的 from_omniauth 它不会保存如果用户记录已经存在。

P.S。从您的示例代码中,Oauth 信息直接保存到 User 模型(provideruid)。这样一来,恐怕用户将无法同时使用 Facebook 和 Google 登录,因为两者都想保存到这两个字段。

更新: 从我的代码库中粘贴一个模型,该模型与 User 不同,允许多个提供商登录。当然,控制器需要更新以使用 Authorization 而不是 User。以防万一它有帮助。

class Authorization < ActiveRecord::Base
  belongs_to :user

  def self.from_omniauth(auth)
    authorization = where(auth.slice(:provider, :uid)).first_or_create
    return authorization if authorization.user

    if user = User.where(email: auth.info.email).first
      authorization.bind_user(user)
    else
      user = authorization.create_user(auth.info)
    end

    authorization
  end

  def bind_user(user)
    self.user = user
    save
  end

  def create_user(info)
    user = User.new(
      email:      info.email,
      password:   Devise.friendly_token[0, 20],
      first_name: info.first_name,
      last_name:  info.last_name,
    )
    user.save(validate: false)

    bind_user(user)

    user
  end
end