我正在使用omniauth-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检索电子邮件地址,因此我的验证规则导致登录失败:
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登录)。
有没有人有任何建议?
修改
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>
答案 0 :(得分: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信息。