很长的问题,但我想我会尽力彻底。 :)
我已按照本教程“如何:允许用户使用其用户名或电子邮件地址登录”:
所以我显然不是这方面的专家!我在这里也看过一些类似的帖子,但是对我来说没有任何效果。
基本上我想设置我的应用,以便用户使用用户名和密码注册,而不是电子邮件地址。不关心获取用户的电子邮件地址或任何类型的密码恢复。只需要简单的UN和密码验证。我的注册工作正常。我可以整天创建新用户。但是,在注销用户后,我无法重新登录。我收到“无效的用户名或密码”消息。
以下是我正在使用的内容:
在控制台中,我收到以下401身份验证错误:
Started POST "/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
有问题的观点(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"
还
#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
我错过了什么?
编辑和解决方案
所以在我完成上述教程之前,我又回过头来。
以下是我解决问题的方法。首先,我决定在user模型中包含在devise.rb中注释掉的authentication_key变量(:validatable,:authentication_keys =&gt; [:username])
我将其更改为:email to:username。我也做了:用户名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
然后我更新了视图,以便:不需要和添加电子邮件:用户名字段...
SIGNUP
%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"
并登录
%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 :(得分:0)
我认为这里不需要虚拟属性login
,你可以通过:username
来实现这一点。
无论如何,我认为问题出在你看来。您需要将输入字段更改为: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"
答案 1 :(得分: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 ]
然后更改表单以处理用户名而不是电子邮件。
这对我有用,所以我希望它有所帮助! (使用Rails 4和设计3)