我需要使用电话号码或电子邮件地址登录该应用程序。我正在使用devise 3.5.2进行身份验证。根据这篇文章(Devise sign up either by email or by mobile number),我实现了以下内容。
application_controller.rb
before_action :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
added_attrs = [:phone, :email, :password, :password_confirmation, :remember_me]
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(added_attrs) }
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(added_attrs) }
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(added_attrs) }
end
user.rb
attr_accessor :email_confirmation, :login
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :authentication_keys => [:login]
def login=(login)
@login = self.email
end
def login
@login || self.phone || self.email
end
配置/初始化/ devise.rb
config.authentication_keys = [ :login ]
现在,如果我尝试使用电子邮件或电话号码登录,我将收到未经授权的"错误。样本请求如下。
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"hCUuF5Ja9f37I4ZBSafGvCpgTnF1nKWf+q8aTEv28mW6vx3z+hIietmYjX9vi0/l/bjVqj0jDaV88mvmdXn9Vg==", "user"=>{"email"=>"jen@companyadmin.com", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"uRnINI6Bogx3yeAP8WNpZB31jNOWnvvWVhHJg1BMZL2Hg/vQ5sl1i1Vy6zHXT+A9yi0XCN4hU+zQTLgpbsNrjg==", "user"=>{"email"=>"1234567890", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Log in"}
对于这两个请求,响应是
Completed 401 Unauthorized in 2ms
有关如何解决这个问题的想法吗?
答案 0 :(得分:2)
通过您共享的参数,电话或电子邮件将被发送到email
命名的参数。相反它应该是login
。
如果您的视图代码接受电子邮件或电话号码
<%= f.text_field :email %>
<%= f.text_field :phone %>
然后用
替换它<%= f.text_field :login %>
这样,发送的参数将是登录,休息将由您的代码处理。让我知道这是否仍然给您错误。请参阅this link。除了使用用户名之外,它实现相同的功能另请注意modifying views。这似乎是你的问题。其他一切似乎都是正确的。
答案 1 :(得分:1)
您应该覆盖默认登录行为。
User.rb(将此代码放在user.rb模型中)
def self.find_for_database_authentication(warden_conditions)
conditions = warden_conditions.dup
if login = conditions.delete(:login)
where(conditions.to_hash).where(["lower(phone) ILIKE '%#{login.downcase}%' OR lower(email) = :value", { :value => login.downcase }]).first
elsif conditions.has_key?(:phone) || conditions.has_key?(:email)
where(conditions.to_hash).first
end
end