Remember Me 真实性令牌无效 rails

Remember Me authenticity token not working rails

我按照 RailsCast 274 将记住我和重置密码功能添加到我的应用程序。

我在本地没有问题,该应用程序似乎 运行 并且可以很好地验证用户。问题是当我将生产版本部署到 Heroku 时出现错误:

undefined method `find_by_auth_token!' for #<Class:0x007f35fbe37a78>

current_user 在我的 ApplicationController 中定义为:

class ApplicationController < ActionController::Base

  protect_from_forgery with: :exception

  helper_method :current_user
  before_action :require_user

  def current_user
    @current_user ||= User.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
  end

  def require_user
    if current_user.nil?
      redirect_to new_session_path
    end
  end
end

这是我的 SessionsController:

class SessionsController < ApplicationController
  layout false
  skip_before_action :require_user

  def create
    user = User.find_by(email: params["email"])
    if user && user.authenticate(params["password"])
      if params[:remember_me]
        cookies.permanent[:auth_token] = user.auth_token
      else
        cookies[:auth_token] = user.auth_token
      end

      redirect_to root_path, notice: "Login successful!"
    else
      redirect_to new_session_path, alert: "Email or password incorrect"
    end
  end

  def destroy
    cookies.delete(:auth_token)
    redirect_to new_session_path, notice: "Logout successful!"
  end
end

这是 User 模型:

class User < ActiveRecord::Base
  has_secure_password

  has_one :patient, :dependent => :destroy
  has_one :clinician, :dependent => :destroy
  accepts_nested_attributes_for :patient,  :allow_destroy => true 
  accepts_nested_attributes_for :clinician,  :allow_destroy => true

  validates :password,
    :length => { :minimum => 6 }, :if => :password_digest_changed?
  validates_presence_of     :password, on: :create

  before_validation(on: :update) do
    # only want confirmation validation to run if user enters password
    self.password_confirmation = nil unless self.password.present?
  end

  # validates_uniqueness_of :email

  before_create { generate_token(:auth_token) }

  def send_password_reset
    generate_token(:password_reset_token)
    self.password_reset_sent_at = Time.zone.now
    save!
    UserMailer.password_reset(self).deliver
  end

  def generate_token(column)
    begin
      self[column] = SecureRandom.urlsafe_base64
    end while User.exists?(column => self[column])
  end
end

在我的 schema.rb 中:

create_table "users", force: true do |t|
  t.string   "timezone"
  t.boolean  "terms_agreement",        default: false
  t.string   "email"
  t.string   "password_digest"
  t.string   "auth_token"
  t.string   "password_reset_token"
  t.datetime "password_reset_sent_at"
end

为什么这适用于开发而不是生产?

Ruby 2.2.1 & Rails 4.1.8

发展: PostgresSQL 9.4.1

这是一个旧教程,rails 4 个有不同的动态匹配器

Rails 3

User.find_by_auth_token!(cookies[:auth_token])

Rails 4

User.find_by!(auth_token: cookies[:auth_token])