0

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

用户.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

session_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 检索电子邮件地址,因此由于我的验证规则,登录失败:

用户.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+\-.]+@[a-z\d\-.]+\.[a-z]+\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 

我想让用户输入电子邮件,这样他们就可以登录而不会验证失败(仅限 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:

<% provide(:title, 'Enter your email') %>
<h1>Enter your email</h1>

    <div class="row">
      <div class="span6 offset3">
        <%= form_for(@user) do |f| %>
          <%= render 'shared/error_messages', object: f.object %>

          <%= f.label :email %>
          <%= f.text_field :email %>

          <%= f.hidden_field :provider, value: params[:oprovider] %>
          <%= f.hidden_field :provider, value: params[:oprovider] %>
          <%= f.hidden_field :uid, value: params[:ouid] %>
          <%= f.hidden_field :name, value: params[:oname] %>
          <%= f.hidden_field :password , value: params[:opassword] %>
          <%= f.hidden_field :password_confirmation, value: params[:opassword_confirmation] %>

          <% # To know to which form to redirect in case of validation error %>
          <%= hidden_field_tag 'form_name', 'enter_email' %>

          <%= f.submit "Create my account", class: "btn btn-large btn-primary" %>
        <% end %>
      </div>
    </div>
4

1 回答 1

1

创建用户后,它将无效,因为它将缺少所需的电子邮件。因此,当用户保存失败时,您应该将您从 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 信息。

于 2012-11-05T02:34:04.393 回答