Ruby on rails designe/OmniAuth:注册和登录的不同逻辑
默认设计授权路径(即提及的用户\u omniauth\u Authority\u路径)似乎设计为可用于omniauth注册和登录。在OmniAuthCallbackController中接收到auth时,rails应用程序通常使用auth信息来创建新用户或更新现有用户,而不管该用户是否打算登录或注册服务(即Facebook) 我的利益相关者已请求不同的身份验证和登录行为。如果用户单击“向Facebook注册”,但他们的Facebook电子邮件中没有帐户,他们希望继续使用该电子邮件创建帐户。但是,如果用户单击“使用Facebook登录”,但其Facebook电子邮件中没有帐户,他们会向用户显示一条错误消息,解释“您使用的Facebook帐户与我们记录中的帐户不匹配。请使用您的barre3电子邮件和密码登录” 这种逻辑似乎存在于OmniAuthCallbackController的Facebook方法中。将用户的意图(“登录”或“注册”)传递到此回调方法中最干净的方法是什么 如果用户单击“向Facebook注册”,但他们的Facebook电子邮件没有帐户,他们希望继续使用该电子邮件创建帐户 这个假设是无效的,因为Facebook只需要一个电话号码就可以创建。即使用户有电子邮件,从Facebook获取用户电子邮件也需要额外的权限。 您的应用程序应该验证facebook API而不是电子邮件返回的facebook\u uid 将用户的意图(“登录”或“注册”)传递到此回调方法中最干净的方法是什么 对于OmniAuth,“登录”和“注册”之间没有区别。它所做的只是尝试使用提供的Facebook令牌对用户进行身份验证。Ruby on rails designe/OmniAuth:注册和登录的不同逻辑,ruby-on-rails,ruby-on-rails-4,devise,omniauth,Ruby On Rails,Ruby On Rails 4,Devise,Omniauth,默认设计授权路径(即提及的用户\u omniauth\u Authority\u路径)似乎设计为可用于omniauth注册和登录。在OmniAuthCallbackController中接收到auth时,rails应用程序通常使用auth信息来创建新用户或更新现有用户,而不管该用户是否打算登录或注册服务(即Facebook) 我的利益相关者已请求不同的身份验证和登录行为。如果用户单击“向Facebook注册”,但他们的Facebook电子邮件中没有帐户,他们希望继续使用该电子邮件创建帐户。但是,
一种清晰的区分方式是在控制器级别进行分离。如果用户尝试登录,请调用SessionController#create;如果用户尝试注册,请调用UsersController#create。您可以从授权中获取参数,通过在授权URL上添加一些参数来指示用户的意图 例如:
- if devise_mapping.omniauthable?
- resource_class.omniauth_providers.each do |provider|
= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider, {intent: :sign_in})
(这会创建一个URL,如:)
然后,在回调控制器中(无论您如何命名):
class Users::OmniAuthCallbackController
我也对答案进行了太多的研究,但没有得到任何令人满意的答案,因此我向前迈出了一步,创建了能够根据需要工作的功能@杰森的回答帮助我到达这里
视图/users/sessions/new.html.erb
<% if devise_mapping.omniauthable? %>
<% resource_class.omniauth_providers.each do |provider| %>
<%= link_to omniauth_authorize_path(resource_name, provider, {intent: :sign_in}) do %>
<i class="fa fa-<%= provider.to_s.split('_')[0] %>"></i>
<% end %>
<% end %>
<% end %>
<% if devise_mapping.omniauthable? %>
<% resource_class.omniauth_providers.each do |provider| %>
<%= link_to omniauth_authorize_path(resource_name, provider, {intent: :sign_up}) do %>
<i class="fa fa-<%= provider.to_s.split('_')[0] %>"></i>
<% end %>
<% end %>
<% end %>
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
def self.provides_callback_for(provider)
class_eval %Q{
def #{provider}
if request.env["omniauth.params"]["intent"] == "sign_up"
@user = User.from_omniauth_sign_up(request.env['omniauth.auth'])
elsif request.env["omniauth.params"]["intent"] == "sign_in"
@user = User.from_omniauth_sign_in(request.env['omniauth.auth'])
end
if @user.present?
sign_in_and_redirect @user, event: :authentication
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
else
flash[:errors] = {:email => "is not registered with us."}
session["devise.#{provider}_data"] = request.env["omniauth.auth"]
redirect_to new_user_registration_url
end
end
}
end
[:google_oauth2, :facebook, :linkedin].each do |provider|
provides_callback_for provider
end
end
def self.from_omniauth_sign_up(auth)
# check if email address obtained from auth server is in User table
user = User.where(email: auth[:info][:email]).first
if user.present?
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.image = auth.info.image
user.provider = auth.provider
user.uid = auth.uid
user.save
else
user = User.new(provider: auth.provider, uid: auth.uid)
user.email = auth.info.email
user.username = "#{auth.uid}-#{auth.provider}"
user.password = Devise.friendly_token[0,20]
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.image = auth.info.image
user.status_id = 2
user.skip_mobile_validation = true
user.skip_confirmation!
user.save
end
user
end
def self.from_omniauth_sign_in(auth)
if user = User.where(email: auth[:info][:email]).first
user
end
end
是否有办法确定用户的创建(首次登录)并将其重定向到欢迎页面?仅使用Omniauth。
def self.from_omniauth_sign_up(auth)
# check if email address obtained from auth server is in User table
user = User.where(email: auth[:info][:email]).first
if user.present?
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.image = auth.info.image
user.provider = auth.provider
user.uid = auth.uid
user.save
else
user = User.new(provider: auth.provider, uid: auth.uid)
user.email = auth.info.email
user.username = "#{auth.uid}-#{auth.provider}"
user.password = Devise.friendly_token[0,20]
user.first_name = auth.info.first_name
user.last_name = auth.info.last_name
user.image = auth.info.image
user.status_id = 2
user.skip_mobile_validation = true
user.skip_confirmation!
user.save
end
user
end
def self.from_omniauth_sign_in(auth)
if user = User.where(email: auth[:info][:email]).first
user
end
end