【问题标题】:Devise/Omniauth - How to deal with a Provider that doesn't include an email设计/Omniauth - 如何处理不包含电子邮件的提供商
【发布时间】:2012-03-11 01:05:43
【问题描述】:

我有一个使用 Devise 和 Omniauth 来处理身份验证的 Rails 应用程序。按照规定,我在我的 omniauth_callbacks_controller 中接收来自提供商的回调,在那里我检查身份验证是否已经存在,以及是否已经存在具有提供商提供的电子邮件的用户,如有必要,请创建一个新用户。

我需要为每个用户提供一个有效的电子邮件。我的问题来自 Twitter 的回调。 Twitter 不为其用户提供电子邮件,因此我无法创建有效用户。为了解决这个问题,我将提供商的数据存储在一个会话中,然后我向用户发送新的注册页面,要求他们提交他们的电子邮件地址,以便我可以创建一个有效的用户。提交此表单时,我遇到了问题。该表单创建了一个新用户,但很可能已经存在具有该电子邮件的用户(在这种情况下,我需要为该用户添加身份验证)。

目前我正在检查是否已经存在与新用户具有相同电子邮件的用户。如果是这样,我将忽略新用户并将身份验证应用于已存在的用户。然而,这感觉真的很hacky。

我该怎么做?

class Users::RegistrationsController < Devise::RegistrationsController

def build_resource(*args)
    super
    if session[:omniauth]
      #If a user with this email already exists then use them instead
      existing_user = User.find_by_email(@user.email)
      if(existing_user)
          existing_user.email = @user.email
          @user = existing_user
      end
      #If there is a session available, we know it contains data for adding an authentication
      @user.apply_omniauth_data_as_authentication(session[:omniauth])
      #Ensure validations are passed on to next page
      @user.valid?
    end
  end

【问题讨论】:

  • 您解决了这个问题吗?我也有同样的问题。
  • @Finnnn 刚刚在答案中发布了我的 Omniauth 回调控制器。

标签: ruby-on-rails ruby-on-rails-3 twitter devise omniauth


【解决方案1】:

给你。如果我这样做了,我会试着记住我从哪里得到修复并发布一个链接:

class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController

  # This controller handles callbacks from Omniauth providers. If a user already exists with this provider we sign them in.
  # Otherwise we either add an authentication to the current user, or create a new user if one doesn't exist.

  def facebook
    authorize
  end

  def twitter
    authorize
  end

  private

    def authorize
      omniauth_data = request.env["omniauth.auth"]
      #Check to see if we have an authentication for this provider already stored for any User
      authentication = Authentication.find_by_provider_and_uid(omniauth_data['provider'], omniauth_data['uid'])
      #If an authentication already exists, sign the owning User in
      if authentication
        flash[:notice] = "Signed in successfully with " +  omniauth_data['provider'].titleize
        sign_in_and_redirect(:user, authentication.user)
      #Otherwise if there is a current User, add a new authentication for them
      elsif current_user
        current_user.authentications.create(:provider => omniauth_data['provider'], :uid => omniauth_data['uid'], :token => omniauth_data['token'])
        flash[:notice] = "Authentication successful"
        redirect_to user_profile_url
      #Otherwise we check if a user exists with the email address provided by the provider (if provided at all))
      else
        email = omniauth_data['info']['email']
        user = User.find_by_email(email)
        #If no user exists, create a new one
        if(!email || !user)
            user = User.new
        end
        user.apply_omniauth_data_as_authentication(omniauth_data)
        #If they save successfully (meaning we have enough data from the authorisation) sign them in
        if user.email?
          #We got all we needed from the provider so we don't need them to confirm'
          user.skip_confirmation!
          user.save!
          flash[:notice] = "Signed in successfully with " +  omniauth_data['provider']
          sign_in_and_redirect(:user, user)
        #Otherwise we need to have the visitor manually submit missing information
        else
          #save the omniauth data in a session so we can add the authentication once registration is complete
          flash[:alert] = "Please complete registration"
          session[:omniauth] = omniauth_data.except('extra')
          redirect_to new_user_registration_url
        end
      end
    end

end

【讨论】:

    【解决方案2】:

    我喜欢这个链接http://www.orhancanceylan.com/rails-twitter-and-facebook-authentications-with-omniauth-and-devise/使用的解决方案

    它使用提供者凭据在正常的设计过程中注册(以及在用户或单独的表上填写提供者和 uid 属性)。因此,当新用户尝试使用提供商注册时,他们将被要求输入电子邮件和密码,从而减少麻烦(比如想以正常方式登录,但没有密码可以输入,然后你必须处理它)。

    虽然此解决方案在某种程度上否定了首次在社交媒体上注册的便利性,但它以最少的努力创造了长期的有益效果。

    如果您因为害怕失去注册或让您的网站看起来不那么优美而绝对不想要这种要求,请寻找另一种解决方案并完成所有工作来处理这些下游案例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-16
      • 2020-06-25
      • 2019-12-24
      相关资源
      最近更新 更多