Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/53.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails designe/OmniAuth:注册和登录的不同逻辑_Ruby On Rails_Ruby On Rails 4_Devise_Omniauth - Fatal编程技术网

Ruby on rails designe/OmniAuth:注册和登录的不同逻辑

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电子邮件中没有帐户,他们希望继续使用该电子邮件创建帐户。但是,

默认设计授权路径(即提及的用户\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令牌对用户进行身份验证。
一种清晰的区分方式是在控制器级别进行分离。如果用户尝试登录,请调用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