2013-08-24 5 views
2

긴 질문이지만 철저한 시도가 필요하다고 생각했습니다. "사용자가 자신의 이름이나 이메일 주소를 사용하여 로그인 할 수 있도록 허용 방법"Devise 로그인 문제 : Rails 3.2.14

https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-sign-in-using-their-username-or-email-address

그래서 나는 명확에서가 아니라 전문가는 아니지만 :

나는이 튜토리얼을 따라했습니다! 나는 또한 비슷한 게시물 몇 개를 보았지만 아무것도 아직 나를 위해 일하지 않았다.

기본적으로 사용자가 이메일 주소가 아닌 사용자 이름과 비밀번호로 가입하도록 앱을 설정하려고합니다. 사용자의 이메일 주소 또는 모든 종류의 비밀번호 복구를받는 것에 관심이 없습니다. 간단한 UN 및 비밀번호 인증 만 있으면됩니다. 내 가입은 잘 작동합니다. 하루 종일 새로운 사용자를 만들 수 있습니다. 그러나 사용자가 로그 아웃 한 후에 다시 로그인 할 수 없습니다. "잘못된 사용자 이름 또는 비밀번호"메시지가 표시됩니다.

Started POST "https://stackoverflow.com/users/sign_in" for 127.0.0.1 at 2013-08-24 17:52:15 -0500 
Processing by Devise::SessionsController#create as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"HIFrqmz+LFMTzeULLDedlonWmtUGU0bniseLwcxtv64=", "user"=>{"username"=>"bobbiebear", "password"=>"[FILTERED]", "remember_me"=>"0"}, "commit"=>"Sign in"} 
Completed 401 Unauthorized in 1ms 

내 사용자 모델 user.rb은 다음과 같습니다 :

class User < ActiveRecord::Base 
    rolify 
    # Include default devise modules. Others available are: 
    # :token_authenticatable, :confirmable, 
    # :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable 

    # Setup accessible (or protected) attributes for your model 
    attr_accessible :role_ids, :as => :admin 
    attr_accessible :username, :password, :password_confirmation, :remember_me 
    attr_accessible :login 
    #attr_accessible :email 

    # Virtual attribute for authenticating by either username or email 
    # This is in addition to a real persisted field like 'username' 
    attr_accessor :login 

    def self.find_first_by_auth_conditions(warden_conditions) 
    conditions = warden_conditions.dup 
    if login = conditions.delete(:login) 
     where(conditions).where(["lower(username) = :value OR lower(email) = :value", { :value => login.downcase }]).first 
    else 
     where(conditions).first 
    end 
    end 


### This is the correct method you override with the code above 
### def self.find_for_database_authentication(warden_conditions) 
### end 

    def email_required? 
    false 
    end 

    def email_changed? 
    false 
    end 

end 

그리고 401 인증 오류 다음 내가 얻을 콘솔에서

: 여기

내가 함께 일하고 있어요 무엇 문제의보기 (HAML) :

%h2 Sign in 
= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => {:class => 'form-vertical' }) do |f| 
    = f.input :username, :autofocus => true 
    = f.input :password 
    = f.input :remember_me, :as => :boolean if devise_mapping.rememberable? 
    = f.button :submit, "Sign in", :class => 'btn-primary' 
= render "devise/shared/links" 
(210)

또한

#devise.rb 
Devise.setup do |config| 
    config.authentication_keys = [ :login ] 
    config.confirmation_keys = [ :login ] 
    config.unlock_keys = [ :login ] 
    config.stretches = Rails.env.test? ? 1 : 10 
    config.password_length = 8..128 
    config.sign_out_via = Rails.env.test? ? :get : :delete 
end 

그리고 바로이 어떤 통찰력을 제공하는 경우, 내 스키마

ActiveRecord::Schema.define(:version => 20130824210400) do 

    create_table "roles", :force => true do |t| 
    t.string "name" 
    t.integer "resource_id" 
    t.string "resource_type" 
    t.datetime "created_at", :null => false 
    t.datetime "updated_at", :null => false 
    end 

    add_index "roles", ["name", "resource_type", "resource_id"], :name => "index_roles_on_name_and_resource_type_and_resource_id" 
    add_index "roles", ["name"], :name => "index_roles_on_name" 

    create_table "users", :force => true do |t| 
    t.string "email",     :default => "" 
    t.string "encrypted_password",  :default => "", :null => false 
    t.string "reset_password_token" 
    t.datetime "reset_password_sent_at" 
    t.datetime "remember_created_at" 
    t.integer "sign_in_count",   :default => 0 
    t.datetime "current_sign_in_at" 
    t.datetime "last_sign_in_at" 
    t.string "current_sign_in_ip" 
    t.string "last_sign_in_ip" 
    t.datetime "created_at",        :null => false 
    t.datetime "updated_at",        :null => false 
    t.string "name" 
    t.string "username" 
    end 

    add_index "users", ["email"], :name => "index_users_on_email" 
    add_index "users", ["reset_password_token"], :name => "index_users_on_reset_password_token", :unique => true 
    add_index "users", ["username"], :name => "index_users_on_username", :unique => true 

    create_table "users_roles", :id => false, :force => true do |t| 
    t.integer "user_id" 
    t.integer "role_id" 
    end 

    add_index "users_roles", ["user_id", "role_id"], :name => "index_users_roles_on_user_id_and_role_id" 

end 

나는 무엇을 놓치고?

그래서 다시 내가 위에서 언급 한 자습서를 가기 전에에 복귀

편집 및 솔루션입니다.

다음은 문제를 해결 한 방법입니다. 먼저, 사용자 모델 (: validatable, : authentication_keys => [: username])에 devise.rb에 주석 처리 된 authentication_key 변수를 포함하기로 결정했습니다.

전자 메일 주소 : 사용자 이름으로 변경했습니다. 나는 또한 만들었다 : 사용자 이름 attr_accessible. 그리고 마침내는 사용자 모델

def email_required? 
    false 
    end 

    def email_changed? 
    false 
    end 

그래서 추가 된 지금은이 : 이메일 필요하며 추가되지 않은 : 그 때문에

class User < ActiveRecord::Base 
    rolify 
    # Include default devise modules. Others available are: 
    # :token_authenticatable, :confirmable, 
    # :lockable, :timeoutable and :omniauthable 

    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, 
     :validatable, :authentication_keys => [:username] 

    # Setup accessible (or protected) attributes for your model 
    attr_accessible :role_ids, :as => :admin 
    attr_accessible :name, :username, :email, :password, :password_confirmation, :remember_me 

    def email_required? 
    false 
    end 

    def email_changed? 
    false 
    end 

end 

그럼 내가보기를 업데이트 된 사용자 이름 필드를 ...

약관 동의

%h2 Sign up 
= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name), :html => {:class => 'form-vertical' }) do |f| 
    = f.error_notification 
    = display_base_errors resource 
    = f.input :name, :autofocus => true 
    -#= f.input :email, :required => true 
    = f.input :username, :required => true 
    = f.input :password, :required => true 
    = f.input :password_confirmation, :required => true 
    = f.button :submit, 'Sign up', :class => 'btn-primary' 
= render "devise/shared/links" 

을 그리고 난 당신이 단지 :username 사용하여이를 달성 할 수, 가상 속성 login 정말 여기에 필요하다 생각하지 않는다

%h2 Sign in 
= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => {:class => 'form-vertical' }) do |f| 
    -#= f.input :email, :autofocus => true 
    = f.input :username, :autofocus => true 
    = f.input :password 
    = f.input :remember_me, :as => :boolean if devise_mapping.rememberable? 
    = f.button :submit, "Sign in", :class => 'btn-primary' 
= render "devise/shared/links" 

답변

0

당신이 이미 작동하지만, 여기가있어 확실하지.

#app/views/devise/registrations/new.html.erb 

<%= f.label :username %> 
<%= f.text_field :username %> 


#config/initializers/devise.rb 

config.authentication_keys = [ :email ] 

to 

config.authentication_keys = [ :username ] 

그런 다음 전자 메일 대신 사용자 이름을 처리하도록 양식을 변경하십시오.

이것은 저에게 도움이되었으므로 도움이되기를 바랍니다. (레일 4와 3을 가지고)

+1

감사합니다! 나는 또한'def email_required? 거짓 끝 def email_changed? false end'을 (를) 내 사용자 등급으로 변경하십시오. – mrilikecoding

0

에 로그인합니다.

어쨌든, 나는 문제가 당신의 견해에 있다고 생각합니다. 당신은 :login 될 당신의 입력 필드를 변경해야하지 :username이 좋아 다음과

%h2 Sign in 
= simple_form_for(resource, :as => resource_name, :url => session_path(resource_name), :html => {:class => 'form-vertical' }) do |f| 
    = f.input :login, :autofocus => true 
    = f.input :password 
    = f.input :remember_me, :as => :boolean if devise_mapping.rememberable? 
    = f.button :submit, "Sign in", :class => 'btn-primary' 
= render "devise/shared/links" 
+0

답장을 보내 주셔서 감사합니다. 내가 제안한대로보기를 전환 할 때도 여전히 동일한 결과가 표시됩니다. 너는 나에게 영감을 주었다. 내가 튜토리얼을하기 전에 다시 되돌 렸고 문제를 해결했다고 생각합니다. – mrilikecoding