2013-11-22 180 views
1

我試圖讓用戶使用其用戶名或電子郵件地址登錄。Rails 4 + Devise 3.0 - 使用用戶名和電子郵件進行身份驗證

按這裏:https://github.com/plataformatec/devise/wiki/How-To:-Allow-users-to-sign-in-using-their-username-or-email-address

當過我嘗試使用任何電子郵件或此登錄登錄登錄:

Started POST "https://stackoverflow.com/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是不檢查的用戶名,所以也許在用戶的電話是錯誤的,但它正是從設計文件。

我已閱讀以下內容:

Adding Username to devise rails 4 Logging in with username using Devise with Rails 4

我還審查了監獄長代碼和代碼色器件嘗試和探索,如果我重寫的用戶錯誤的方法。

任何想法爲什麼它不通過用戶名進行身份驗證,當它使用電子郵件?

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

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 

回答

3

您需要添加

config.authentication_keys = [ :login ] 

內devise.rb

另外,如果你想使用登錄復位密碼或進行確認鍵,你還應該添加在同一文件中:

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

你還需要將您的application_controller中的登錄參數列入白名單。在new.html視圖中,您有一個登錄表單,因此您必須接受sign_in的登錄參數,而不是用戶名和電子郵件參數。

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

非常感謝你! – Rtype

相關問題