允许用户使用Twitter登录(OmniAuth)时输入电子邮件 [英] Enabling users to enter their email when they login with Twitter (OmniAuth)

查看:145
本文介绍了允许用户使用Twitter登录(OmniAuth)时输入电子邮件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using omniauth-twitter and I have everything set up:

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

The problem is that you can't retrieve an email address from Twitter, so the login fails because of my validation rules:

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+\-.]+@[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登录名).

I want to enable users to enter an email so they can login without failing the validation (only with Twitter, since I have Facebook and Google login too).

有人有什么建议吗?

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

users/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>

推荐答案

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

When the user is created it will be invalid since it will be missing the required email. So when the user save fails, you should put the information you retrieved from Twitter in the session and redirect the user to a registration page where he can input his email. Basically, this:

# 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哈希,因为它通常包含许多我们不需要的信息.如果确实需要,请小心,因为会话有一定的大小限制,有时您无法容纳其中的所有内容.

You'll notice that we are discarding the extra hash because it usually contains a lot of information that we don't need. If you do need it, be careful because the session has a certain size limit and sometimes you can't fit everything in there.

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

Now you need to create a registrations controller with the new action (to show a page where the user will input his email) and the create action (where you will use the Twitter info to further customize your new user).

# 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信息.

Finally, if the user is valid and saved then we can safely destroy the Twitter info from the session.

这篇关于允许用户使用Twitter登录(OmniAuth)时输入电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆