设计登录后,Devise不会将用户发送到root用户

时间:2018-02-06 15:39:47

标签: ruby-on-rails devise

Devise的默认行为应该是在登录后将用户发送到根路径。我没有做到这一点,而只是再次渲染登录页面。它正在记录用户。它只是没有正确重定向。

development.log(显示用户操作的注释)

# Starting from root

Started GET "/" for 127.0.0.1 at 2018-02-06 23:11:21 +0800
Processing by JobsController#index as HTML
  Rendering jobs/index.html.haml within layouts/application
  [1m[36mJob Load (0.8ms)[0m  [1m[34mSELECT "jobs".* FROM "jobs" ORDER BY created_at DESC[0m
  Rendered jobs/index.html.haml within layouts/application (23.8ms)
Completed 200 OK in 366ms (Views: 352.8ms | ActiveRecord: 3.3ms)

# Click 'Sign In' link

Started GET "/users/sign_in" for 127.0.0.1 at 2018-02-06 23:11:22 +0800
Processing by Devise::SessionsController#new as HTML
  Rendering devise/sessions/new.html.haml within layouts/application
  Rendered devise/sessions/new.html.haml within layouts/application (36.9ms)
Completed 200 OK in 87ms (Views: 84.6ms | ActiveRecord: 0.0ms)

# Fill in username and password and submit

Started POST "/users/sign_in" for 127.0.0.1 at 2018-02-06 23:11:47 +0800
Processing by Devise::SessionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"Ahemte4a2+/IEs3Fgiz9GRiu5GesxdWv5ZDK1sC0gqm0yerpppH+xGfktJvUyQOcgsjoEZlPqt/dy+I5tkLJjw==", "user"=>{"login"=>"josh", "password"=>"[FILTERED]", "remember_me"=>"1"}, "commit"=>"Log in"}
  [1m[36mUser Load (0.8ms)[0m  [1m[34mSELECT  "users".* FROM "users" WHERE (lower(username) = 'josh' OR lower(email) = 'josh') ORDER BY "users"."id" ASC LIMIT $1[0m  [["LIMIT", 1]]
  [1m[35m (0.2ms)[0m  [1m[35mBEGIN[0m
  [1m[35mSQL (0.5ms)[0m  [1m[33mUPDATE "users" SET "remember_created_at" = $1, "updated_at" = $2 WHERE "users"."id" = $3[0m  [["remember_created_at", "2018-02-06 15:11:47.637205"], ["updated_at", "2018-02-06 15:11:47.637995"], ["id", 1]]
  [1m[35m (20.0ms)[0m  [1m[35mCOMMIT[0m
  [1m[35m (0.3ms)[0m  [1m[35mBEGIN[0m
  [1m[36mUser Exists (0.7ms)[0m  [1m[34mSELECT  1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER($1) AND ("users"."id" != $2) LIMIT $3[0m  [["username", "josh"], ["id", 1], ["LIMIT", 1]]
  [1m[36mUser Exists (0.5ms)[0m  [1m[34mSELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER($1) AND ("users"."id" != $2) LIMIT $3[0m  [["email", "joshuaikesling@gmail.com"], ["id", 1], ["LIMIT", 1]]
  [1m[36mUser Exists (0.5ms)[0m  [1m[34mSELECT  1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2[0m  [["email", "josh"], ["LIMIT", 1]]
  [1m[35m (0.3ms)[0m  [1m[31mROLLBACK[0m
  Rendering devise/sessions/new.html.haml within layouts/application
  Rendered devise/sessions/new.html.haml within layouts/application (8.4ms)
Completed 200 OK in 265ms (Views: 54.6ms | ActiveRecord: 25.6ms)

# Landing back on sign in page (expected result was redirect to root path)

节/ new.html.haml

.row
  .col-sm-6.col-sm-offset-3
    %h2 Log in
    = simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
      .form-inputs
        = f.input :login, required: false, autofocus: true
        = f.input :password, required: false
        = f.input :remember_me, as: :boolean, input_html: { checked: true } if devise_mapping.rememberable?
      .form-actions
        = f.button :submit, "Log in", class: 'btn-success', class: 'btn-success'
    %h4.button-alt-link Don't have an account? #{link_to 'Sign up here!', new_user_registration_path}

application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception

  before_action :configure_permitted_parameters, if: :devise_controller?
  before_action :authenticate_user!, except: %i[show index]

  protected

  def after_sign_in_path_for(resource)
    stored_location_for(resource) || request.env['omniauth.origin'] || root_path
  end

  def configure_permitted_parameters
    added_attrs = [:username, :email, :password, :password_confirmation, :remember_me, :admin]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
  end
end

的routes.rb

Rails.application.routes.draw do
  resources :cvs
  devise_for :users
  resources :agents
  resources :jobs

  root to: "jobs#index"
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

初始化/ devise.rb

Devise.setup do |config|

  config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'

  require 'devise/orm/active_record'

  config.authentication_keys = [:login]

  config.case_insensitive_keys = [:email, :username]

  config.strip_whitespace_keys = [:email, :username]

  config.skip_session_storage = [:http_auth]

  config.stretches = Rails.env.test? ? 1 : 11

  config.send_email_changed_notification = true

  config.send_password_change_notification = true

  config.reconfirmable = true

  config.confirmation_keys = [ :username ]

  config.expire_all_remember_me_on_sign_out = true

  config.password_length = 6..128

  config.email_regexp = /\A[^@\s]+@[^@\s]+\z/

  config.lock_strategy = :none

  config.reset_password_keys = [ :username ]

  config.reset_password_within = 6.hours

  config.sign_out_via = :delete

end

的Gemfile

source 'https://rubygems.org'

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
  "https://github.com/#{repo_name}.git"
end

gem 'aws-sdk-rails', '~> 2.0', '>= 2.0.1'
gem 'bootstrap-sass', '~> 3.3', '>= 3.3.7'
gem 'cancancan', '~> 2.1', '>= 2.1.3'
gem 'coffee-rails', '~> 4.2'
gem 'country_select', '~> 3.1', '>= 3.1.1'
gem 'devise', '~> 4.4', '>= 4.4.1'
gem 'haml-rails', '~> 1.0'
gem 'jbuilder', '~> 2.5'
gem 'jquery-rails', '~> 4.3', '>= 4.3.1'
gem 'simple_form', '~> 3.5'
gem "paperclip", "~> 5.2.1"
gem 'pg', '~> 0.18'
gem 'puma', '~> 3.7'
gem 'rails', '~> 5.1.4'
gem 'sass-rails', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'uglifier', '>= 1.3.0'
gem 'validates_timeliness', '~> 4.0', '>= 4.0.2'

group :development, :test do
  gem 'byebug', platforms: %i[mri mingw x64_mingw]
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
end

group :development do
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

user.rb

class User < ApplicationRecord
  has_one :cv

  has_many :educations, through: :cvs, inverse_of: :user
  has_many :languages, through: :cvs, inverse_of: :user
  has_many :jobs

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

  validates :username, presence: true, uniqueness: { case_sensitive: false }, length: { in: 4..50 }
  validates_format_of :username, with: /^[a-zA-Z0-9_\.]*$/, multiline: true
  validates :email, presence: true, uniqueness: { case_sensitive: false }
  validates_format_of :email, with: /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/, multiline: true
  validate :validate_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
      if conditions[:username].nil?
        where(conditions).first
      else
        where(username: conditions[:username]).first
      end
    end
  end

  def validate_username
    errors.add(:username, :invalid) if User.where(email: username).exists?
  end
end

2 个答案:

答案 0 :(得分:1)

我相信你会收到验证错误,基于日志中的回滚:

  ...
  1m[35m (0.3ms)[0m  [1m[35mBEGIN[0m
  [1m[36mUser Exists (0.7ms)[0m  [1m[34mSELECT  1 AS one FROM "users" WHERE LOWER("users"."username") = LOWER($1) AND ("users"."id" != $2) LIMIT $3[0m  [["username", "josh"], ["id", 1], ["LIMIT", 1]]
  [1m[36mUser Exists (0.5ms)[0m  [1m[34mSELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER($1) AND ("users"."id" != $2) LIMIT $3[0m  [["email", "joshuaikesling@gmail.com"], ["id", 1], ["LIMIT", 1]]
  [1m[36mUser Exists (0.5ms)[0m  [1m[34mSELECT  1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2[0m  [["email", "josh"], ["LIMIT", 1]]

  [1m[35m (0.3ms)[0m  [1m[31mROLLBACK[0m

  Rendering devise/sessions/new.html.haml within layouts/application
  ...

可能是由您的用户模型上的某些验证引起的?

确保在应用程序布局中呈现这两个flash消息键,因为这是设计将写入的内容:

flash[:notice]flash[:alert]

旁注:

def configure_permitted_parameters
  added_attrs = [:username, :email, :password, :password_confirmation, :remember_me, :admin]
  devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
  devise_parameter_sanitizer.permit :account_update, keys: added_attrs
end

上面的代码对我来说似乎很粗略,也许不是问题? :admin :sign_up可能不应列入白名单,也许我错了?也许不是account_update没有验证用户是管理员 - 但我没有任何背景,所以也许我不在基地。

Devise的初始化程序已经有一个用于验证电子邮件格式的REGEX。从用户模型中删除验证可以解决问题。模型中的验证为Devise提供了一个无声错误,导致它重新呈现登录页面,即使它已成功签名用户,而不是在登录后将用户重定向到根路径。

答案 1 :(得分:0)

尝试将其添加到ApplicationController.rb

def after_sign_in_path_for(resource)
  root_path
end