如何使用 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
模型(provider
和 uid
)。这样一来,恐怕用户将无法同时使用 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
我正在使用 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
模型(provider
和 uid
)。这样一来,恐怕用户将无法同时使用 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