尝试在Rails中编写用于验证用户名的正则表达式

5
我正在尝试在Ruby(Rails)中编写正则表达式,以便用户名的字符仅包含数字和字母(也没有空格)。
我有这个正则表达式:/^[a-zA-Z0-9]+$/,但它似乎不起作用,并且我在Rails中收到一个错误,提示“提供的正则表达式使用多行锚点(^或$),这可能会造成安全风险。您是否想使用\A和\z,或忘记添加:multiline => true选项?"
我在用户.rb模型中实现的完整代码如下:
class User < ActiveRecord::Base
  before_save { self.email = email.downcase }
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_USERNAME_REGEX = /^[a-zA-Z0-9]+$/
  validates :username, presence: true, length: { maximum: 20 },
                                    format: { with: VALID_USERNAME_REGEX },
                                    uniqueness: { case_sensitive: false }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                format: { with: VALID_EMAIL_REGEX },
                uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, length: { minimum: 6 }
end

我做错了什么,如何修复这个正则表达式,以便它只对数字和字母有效,而不包含空格?谢谢。
2个回答

10

简短回答:使用/\A[a-zA-Z0-9]+\z/代替(正如VALID_EMAIL_REGEX所使用的)。

详细回答:^和$锚点将匹配字符串中每行的开头和结尾。这意味着如果您的字符串由多行字母数字字符组成,则它们将匹配:

/^[a-zA-Z0-9]+$/ =~ "Ana\nBob\nClara\nDaniel"  #=> 0 (matches)
\A\z 与之相反,它们匹配一个字符串的开头和结尾,因此可以防止用户发送多行字符串(例如前面的示例)可能导致的攻击。请注意保留HTML标签。
/\A[a-zA-Z0-9]+\z/ =~ "Ana\nBob\nClara\nDaniel"  #=> nil (doesn't match)
/\A[a-zA-Z0-9]+\z/ =~ "Erika"                    #=> 0   (matches)

2

您只需遵循错误提示。将^(行的开始锚点)替换为\A(字符串的开始锚点),将$(行的结束锚点)替换为\z(字符串的结束锚点)。除此之外,您的正则表达式可以按原样使用。

\A[a-zA-Z0-9]+\z

Rails存在安全隐患,因为与某些语言不同,^$只匹配单行的开头/结尾,而不是整个字符串。
下面是一个可能被利用的例子:
str = "malicious_code()\naValidUsername"
str.match(/^[a-zA-Z0-9]+$/) # => #<MatchData "aValidUsername">

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接