【问题标题】:Rails - Devise, Email Case InsensitivityRails - 设计,电子邮件不区分大小写
【发布时间】:2010-11-10 19:14:50
【问题描述】:

我正在使用带有登录凭据的设计:电子邮件/密码 - 没有用户名

我刚刚注意到登录过程对电子邮件是区分大小写的。因此,如果您在 bob@apPle.com 注册,然后尝试使用 Bob@apple.com 登录,您会收到错误消息。非常混乱。

如何让设计人员使用他们的电子邮件/密码登录,并且电子邮件不区分大小写?

【问题讨论】:

  • 注意:上述行为(从 1.2 开始?)似乎不再是默认行为。

标签: ruby-on-rails ruby-on-rails-3 devise


【解决方案1】:

您可以轻松解决如下问题。

# config/initializers/devise.rb
Devise.setup do |config|
  config.case_insensitive_keys = [:email, :username]
end

【讨论】:

  • 这看起来是使登录不区分大小写的最正确方法。 (它对我有用——谢谢!)
  • 已于 2012 年 2 月 15 日在 Devise 1.4.2 上确认。据我所知,它不在在线 wiki 中
  • 确保运行迁移以降低数据库中任何现有的电子邮件或用户名。
  • 此外,您可能必须使用 <attribute>_will_change! 方法来获取 ActiveRecord 以更改您的数据,因为为模型 AR 设置了 case_insensitive_keys 不再是电子邮件或用户名仅通过小写而更改的事情.
  • 不过,如果您有两个具有不同要求的 Devise 模型(用户/管理员),这不是最佳选择。
【解决方案2】:

一种选择是覆盖设计使用的查找方法。比如:

# User.rb
before_save do
  self.email.downcase! if self.email
end

def self.find_for_authentication(conditions) 
  conditions[:email].downcase! 
  super(conditions) 
end 

【讨论】:

  • 谢谢凯文。无论如何让用户保存他们想要的电子邮件,但是使用 find_for_authentication 来降低输入的内容和数据库中的内容以避免这个问题?想法?
  • 有可能。您很可能必须在没有父调用的情况下覆盖find_for_authentication fully(并自己执行查找),但我不确定传入了什么条件。
  • 有没有人想出解决方案来存储它区分大小写但在登录时使其不区分大小写?
【解决方案3】:

我将此添加到我的用户模型中以区分大小写,但在登录期间使其不区分大小写:

def self.find_for_database_authentication(conditions = {})
  self.where("LOWER(email) = LOWER(?)", conditions[:email]).first || super
end

它适用于 Heroku。

顺便说一句,这只是一个临时修复,因为问题已经解决,这将是 Devise 1.2 的默认行为。详情请见this pull request。

【讨论】:

  • 我真的认为这是最好的答案,尤其是在(某些)用户可以看到电子邮件的应用程序上。人们应该可以根据自己的喜好选择大写电子邮件,而且这不需要更新您当前的数据库。
  • 请注意,拉取请求中的修复不与 Andrés 提供的代码相同。较新的设计将仅在配置时搜索小写的电子邮件,但不能保证电子邮件字段在保存时是小写的。如果使用较新的设计版本在数据库中具有大写字母,则在查找小写电子邮件地址时仍然会遇到问题,而上面的代码将成功查找不同的大写版本。
  • 另请注意,正如the comments here 提到的那样,这只会使电子邮件对身份验证不区分大小写,而不是例如密码重置。
  • 更正,devise 确实会尝试在保存时降低电子邮件的大小写,但如果混合有其他代码,它并不总是成功。
【解决方案4】:

我还有一些解决方案,使所有 Devise 控制器(功能)使用电子邮件不区分大小写:

class ApplicationController < ActionController::Base
...
...
  prepend_before_filter :email_to_downcase, :only => [:create, :update]
...
...
  private
...
...
  def email_to_downcase
    if params[:user] && params[:user][:email]
      params[:user][:email] = params[:user][:email].downcase
    end
  end
...
...
end

我知道这不是最好的解决方案:它涉及另一个模型的另一个控制器并执行它们不需要的代码。但这只是临时的,它有效(至少对我来说)。

Kevin 和 Andres,感谢您的回答。这确实是很好的解决方案并且很有用。我想投票给他们,但我还没有足够的声誉。所以,我只是对你说“谢谢”。 ;)

让我们等待 Devise 1.2

【讨论】:

    【解决方案5】:
    猜你喜欢
    • 1970-01-01
    • 2016-11-25
    • 2012-04-06
    • 2011-09-19
    • 1970-01-01
    • 2020-09-15
    • 2017-05-31
    • 2017-03-22
    • 2018-06-28
    相关资源
    最近更新 更多