允许用户在使用Twitter登录时输入他们的电子邮件(OmniAuth)

我正在使用omn​​iauth-twitter ,我已经完成了所有设置:

user.rb:

def self.create_with_omniauth(auth) create! do |user| user.provider = auth["provider"] user.uid = auth["uid"] user.name = auth["info"]["name"] user.email = auth["info"]["email"] # To pass password validation user.password = user.password_confirmation = SecureRandom.urlsafe_base64(n=6) end end 

sessions_controller.rb:

  def create user = User.find_by_email(params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) sign_in user redirect_back_or user else flash.now[:error] = 'Invalid email/password combination' render 'new' end end 

问题是您无法从Twitter检索电子邮件地址,因此登录因我的validation规则而失败:

user.rb:

  before_save { |user| user.email = email.downcase } before_save :create_remember_token validates :name, presence: true, length: { maximum: 50 } VALID_EMAIL_REGEX = /\A[\w+\-.]+@[az\d\-.]+\.[az]+\z/i validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, uniqueness: { case_sensitive: false } validates :password, presence: true, length: { minimum: 6 } validates :password_confirmation, presence: true 

我想让用户输入一封电子邮件,这样他们就可以登录而不会失败validation(仅限Twitter,因为我也有Facebook和Google登录)。

有没有人有任何建议?

编辑:

users_controller.rb:

  def create @user = User.new(params[:user]) if @user.save sign_in @user flash[:success] = "Welcome to the Sample App!" redirect_to @user else if params[:form_name] == "enter_email" render 'enter_email' else render 'new' end end end 

用户/ enter_email.html.erb:

  

Enter your email

创建用户时,它将无效,因为它将缺少所需的电子邮件。 因此,当用户保存失败时,您应该将从Twitter检索到的信息放入会话中,并将用户重定向到可以输入其电子邮件的注册页面。 基本上,这个:

 # SessionsController def create if user.save sign_in user redirect_to ... else session[:omniauth] = request.env['omniauth.auth'].except('extra') redirect_to new_registration_path end end 

您会注意到我们正在丢弃extra哈希,因为它通常包含我们不需要的大量信息。 如果你确实需要它,请小心,因为会话有一定的大小限制,有时你不能适应那里的一切。

现在,您需要使用new操作创建注册控制器(以显示用户将输入其电子邮件的页面)和create操作(您将使用Twitter信息进一步自定义新用户)。

 # RegistrationsController def create if session[:omniauth] user = User.create_with_email_and_omniauth(params[:user], session[:omniauth]) end session[:omniauth] = nil unless user.new_record? end 

最后,如果用户有效并保存,那么我们可以安全地从会话中销毁Twitter信息。