2

長い質問ですが、徹底しようと思いました。:)

このチュートリアル「方法: ユーザーがユーザー名または電子メール アドレスを使用してサインインできるようにする」に従いました。

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

だから私は明らかにこれの専門家ではありません! ここでも同様の投稿をいくつか見ましたが、まだ何も機能していません。

基本的に、ユーザーがメールアドレスではなくユーザー名とパスワードでサインアップできるようにアプリをセットアップしたいと考えています。ユーザーの電子メール アドレスを取得したり、あらゆる種類のパスワードを回復したりする必要はありません。簡単な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

私は何が欠けていますか?

編集と解決策

そのため、上記のチュートリアルを実行する前に戻りました。

これが私が問題を修正した方法です。まず、devise.rb でコメントアウトされている authentication_key 変数を User モデルに含めることにしました (:validatable, :authentication_keys => [:username])

:email から :username に変更しました。:username attr_accessible も作成しました。それから最後に私は追加しました

  def email_required?
    false
  end

  def email_changed?
    false
  end

したがって、 User モデルの場合、次のようになります。

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

次に、:email が不要になるようにビューを更新し、:username フィールドを追加しました...

サインアップ

%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"
4

2 に答える 2

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とdevise 3を使用)

于 2013-08-25T04:30:59.630 に答える
0

ここではvirtual 属性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"
于 2013-08-25T00:01:36.893 に答える