Rails 4 + Devise 3.0-使用用户名和电子邮件进行身份验证 [英] Rails 4 + Devise 3.0 - Authenticate using username and email

查看:113
本文介绍了Rails 4 + Devise 3.0-使用用户名和电子邮件进行身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试允许用户使用其用户名或电子邮件地址登录。

I'm trying to allow users to sign in with either their username or their email address.

按照此处: https://github.com。 com / plataformatec / devise / wiki /操作方法:允许用户使用其用户名或电子邮件地址登录

每当我尝试使用电子邮件或登录名登录时,都会记录该日志:

When ever I try to sign in with either the email or the login this is logged:

Started POST "/users/sign_in" for 192.168.2.8 at 2013-11-22 10:11:50 +0800
Processing by Devise::SessionsController#create as HTML
  Parameters: {"utf8"=>"â", "authenticity_token"=>"WVTOKWQ8yJAJSu3NmXi3skJ8UC8zXY7qGZj7qbM3cr0=", "user"=>{"email"=>"testuser", "password"=>"password"}, "commit"=>"Sign in"}
  User Load (3.3ms)  SELECT "users".* FROM "users" WHERE "users"."email" = 'testuser' ORDER BY "users"."id" ASC LIMIT 1
Completed 401 Unauthorized in 20ms
Processing by Devise::SessionsController#new as HTML
  Parameters: {"utf8"=>"â", "authenticity_token"=>"WVTOKWQ8yJAJSu3NmXi3skJ8UC8zXY7qGZj7qbM3cr0=", "user"=>{"email"=>"rtype", "password"=>"password"}, "commit"=>"Sign in"}
  Rendered devise/sessions/new.html.erb within layouts/application (6.4ms)
Completed 200 OK in 80ms (Views: 62.6ms | ActiveRecord: 0.0ms)

它怪异的sql不检查用户名,所以也许调用

its weird the sql isn't checking for the username, so maybe the call on the user is wrong, but its exactly from the devise documentation.

我读过以下内容:

添加用户名以设计Rails 4
使用Devise with Rails 4使用用户名登录

我还查看了管理员代码和设计代码,以尝试发现我是否在用户中覆盖了错误的方法。

I also reviewed the warden code and the devise code to try and discover if I'm overriding the wrong method in the user.

任何想知道为什么它不通过用户名进行身份验证,而通过电子邮件进行身份验证?

Any ideas why it is not authenticating with username, when it does with email?

ApplicationController.rb

ApplicationController.rb

class ApplicationController < ActionController::Base
  protect_from_forgery

  before_filter :configure_permitted_parameters, if: :devise_controller?

  protected
    def configure_permitted_parameters
      devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email, :password, :password_confirmation) }
      devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email, :password, :remember_me) }

      # Need to add other user fields like gender etc.
      devise_parameter_sanitizer.for(:account_update) {|u| u.permit(:email, :password, :password_confirmation, :current_password)}
    end
end

User.rb

class User < ActiveRecord::Base

  devise :database_authenticatable, :registerable, :confirmable, :encryptable, :recoverable, :rememberable, :trackable, :validatable

  attr_accessor :login # This is used to add the login for allowing user to sign in with both email or username

  # Validations
  validates :username, presence: true, length: {maximum: 255}, uniqueness: { case_sensitive: false }, format: { with: /\A[a-zA-Z0-9]*\z/, message: "may only contain letters and numbers." }

  # Overwrite devise’s find_for_database_authentication method in user model
  def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
    if login = conditions.delete(:username)
      where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first
    else
      where(conditions).first
    end
  end
end

new.html

<fieldset>
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name),  :html => { :class => 'form-horizontal' }) do |f| %>
  <div class="control-group">
    <%= f.label :login, "Email or Username" %>
    <div class="controls"><%= f.text_field :login, :autofocus => true %></div>
  </div>

  <div class="control-group">
    <%= f.label :password %>
    <div class="controls"><%= f.password_field :password %></div>
  </div>

  <div class="form-actions">
    <%= f.submit "Sign in", :class => "btn btn-primary", data: { disable_with: 'Working...' } %>  <%= link_to "Forgot password?", new_password_path(resource_name), :class => "btn" %>
  </div>
<% end %>
</fieldset>

Devise.rb

Devise.rb

config.secret_key = 'Omitted for security'
config.mailer_sender = 'Omitted for security'
config.case_insensitive_keys = [ :email ]
config.strip_whitespace_keys = [ :email ]
config.skip_session_storage = [:http_auth]
config.stretches = Rails.env.test? ? 1 : 10
config.reconfirmable = true
config.password_length = 8..128
config.reset_password_within = 6.hours
config.encryptor = :sha512
config.sign_out_via = :delete


推荐答案

您需要添加

config.authentication_keys = [ :login ]

在devise.rb之内

within devise.rb

此外,如果要使用登录名作为重置密码或确认密钥,还应该在同一文件中添加:

Also if you want to use login as reset password or confirmation keys you should also add within the same file:

config.reset_password_keys = [ :login ]
config.confirmation_keys = [ :login ]

您还需要将application_controller中的登录参数列入白名单。在new.html视图中,您有一个登录表单,因此您必须接受sign_in的登录参数,而不是用户名和电子邮件参数。

You also need to whitelist the login parameter within your application_controller. In the new.html view you have a login form, so you must accept the login parameter for the sign_in instead of the username and email parameters.

devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :password, :remember_me) }

这篇关于Rails 4 + Devise 3.0-使用用户名和电子邮件进行身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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