Rails 5.2.2 Heroku всегда возвращает приложение [web.1]: FATAL - NameError (неинициализированная константа AuthenticateUser :: JsonWebToken) - PullRequest
0 голосов
/ 30 января 2019

Я следую инструкциям из https://www.pluralsight.com/guides/token-based-authentication-with-ruby-on-rails-5-api с некоторой исправленной ошибкой, она работает хорошо ..

но после развертывания на heroku, когда я хочу получить доступ к аутентификационному маршруту (войдите в систему), я получилкод состояния 500 в инсомии:

{
  "status": 500,
  "error": "Internal Server Error"
}

и в терминале я получил этот код:

2019-01-30T03:07:19.567264+00:00 app[web.1]: I, [2019-01-30T03:07:19.567151 #9]  INFO -- : [49a401d5-1f31-4a88-8299-3c14d07ef160] Started POST "/authenticate" for 125.161.110.130 at 2019-01-30 03:07:19 +0000
2019-01-30T03:07:19.568759+00:00 app[web.1]: I, [2019-01-30T03:07:19.568673 #9]  INFO -- : [49a401d5-1f31-4a88-8299-3c14d07ef160] Processing by AuthenticationController#authenticate as JSON
2019-01-30T03:07:19.569025+00:00 app[web.1]: I, [2019-01-30T03:07:19.568946 #9]  INFO -- : [49a401d5-1f31-4a88-8299-3c14d07ef160]   Parameters: {"email"=>"mymail@rocketmail.com", "password"=>"[FILTERED]", "authentication"=>{"email"=>"mymail@rocketmail.com", "password"=>"[FILTERED]"}}
2019-01-30T03:07:19.609086+00:00 app[web.1]: D, [2019-01-30T03:07:19.608939 #9] DEBUG -- : [49a401d5-1f31-4a88-8299-3c14d07ef160]    (3.5ms)  SET NAMES utf8,  @@SESSION.sql_mode = CONCAT(CONCAT(@@sql_mode, ',STRICT_ALL_TABLES'), ',NO_AUTO_VALUE_ON_ZERO'),  @@SESSION.sql_auto_is_null = 0, @@SESSION.wait_timeout = 2147483
2019-01-30T03:07:19.618191+00:00 app[web.1]: D, [2019-01-30T03:07:19.618074 #9] DEBUG -- : [49a401d5-1f31-4a88-8299-3c14d07ef160]   User Load (3.4ms)  SELECT  `users`.* FROM `users` WHERE `users`.`email` = 'mymail@rocketmail.com' LIMIT 1
2019-01-30T03:07:19.742727+00:00 app[web.1]: I, [2019-01-30T03:07:19.742595 #9]  INFO -- : [49a401d5-1f31-4a88-8299-3c14d07ef160] Completed 500 Internal Server Error in 173ms (ActiveRecord: 10.4ms)
2019-01-30T03:07:19.743582+00:00 app[web.1]: F, [2019-01-30T03:07:19.743490 #9] FATAL -- : [49a401d5-1f31-4a88-8299-3c14d07ef160]
2019-01-30T03:07:19.743681+00:00 app[web.1]: F, [2019-01-30T03:07:19.743602 #9] FATAL -- : [49a401d5-1f31-4a88-8299-3c14d07ef160] NameError (uninitialized constant AuthenticateUser::JsonWebToken):
2019-01-30T03:07:19.743757+00:00 app[web.1]: F, [2019-01-30T03:07:19.743677 #9] FATAL -- : [49a401d5-1f31-4a88-8299-3c14d07ef160]
2019-01-30T03:07:19.743841+00:00 app[web.1]: F, [2019-01-30T03:07:19.743763 #9] FATAL -- : [49a401d5-1f31-4a88-8299-3c14d07ef160] app/commands/authenticate_user.rb:10:in `call'
2019-01-30T03:07:19.743859+00:00 app[web.1]: [49a401d5-1f31-4a88-8299-3c14d07ef160] app/controllers/authentication_controller.rb:5:in `authenticate'

вот мой контроллер authentication_

class AuthenticationController < ApplicationController
  skip_before_action :authenticate_request
  
  def authenticate
    command = AuthenticateUser.call(params[:email], params[:password])
  
    if command.success?
      render json: { auth_token: command.result }
    else
      render json: { error: command.errors }, status: :unauthorized
    end
  end
end

вот мой authenticate_user:

class AuthenticateUser
  prepend SimpleCommand

  def initialize(email, password)
    @email = email
    @password = password
  end

  def call
    JsonWebToken.encode(user_id: user.id) if user
  end

  private

  attr_accessor :email, :password

  def user
    user = User.find_by_email(email)
    return user if user && user.authenticate(password)

    errors.add :user_authentication, 'invalid credentials'
    nil
  end
end

здесь json_web_token:

class JsonWebToken
  class << self
    def encode(payload, exp = 24.hours.from_now)
      payload[:exp] = exp.to_i
      JWT.encode(payload, RubyChallenge::Application.credentials.secret_key_base)
    end
  
    def decode(token)
      body = JWT.decode(token, RubyChallenge::Application.credentials.secret_key_base)[0]
      HashWithIndifferentAccess.new body
    rescue
      nil
    end
  end
end

Я установил переменную окружения RAILS_MASTER_KEY для моей героки с тем же значением, что и содержимое config / master.key: моя конфигурация heroku var

мой Gemfile:

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.5.1'

gem 'rails', '~> 5.2.2'
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
gem 'puma', '~> 3.11'
gem 'bcrypt', '~> 3.1.7'
gem 'jwt'
gem 'simple_command'
gem 'figaro'
gem 'bootsnap', '>= 1.1.0', require: false

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

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

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Заранее спасибо

РЕДАКТИРОВАТЬ:

здесь мой config / application.rb:

require_relative 'boot'

require "rails"
# Pick the frameworks you want:
require "active_model/railtie"
require "active_job/railtie"
require "active_record/railtie"
require "active_storage/engine"
require "action_controller/railtie"
require "action_mailer/railtie"
require "action_view/railtie"
require "action_cable/engine"
# require "sprockets/railtie"
require "rails/test_unit/railtie"


Bundler.require(*Rails.groups)

module RubyChallenge
  class Application < Rails::Application
    config.autoload_paths << Rails.root.join('lib')
    config.api_only = true
  end
end
Кстати, мистер Габбар, за ваше предложение

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

РЕШЕНИЕ:

Измените мой config / application.rb с

module RubyChallenge
  class Application < Rails::Application
    ...
    config.autoload_paths << Rails.root.join('lib')
    ...
  end
end

до

module RubyChallenge
  class Application < Rails::Application
    ...
    config.eager_load_paths << Rails.root.join('lib')
    ...
  end
end

делает его работоспособным, потому что Rails 5 отключает автозагрузку после загрузки приложения в рабочем режиме, спасибо Шайлешу Каламкару Статья

0 голосов
/ 30 января 2019

Возможно, вам не хватает этого: -

По умолчанию любой файл в каталоге приложения загружается автоматически, и вы можете использовать его, не включая его, однако вне этого вам придется загружать его при загрузке приложения.

Чтобы убедиться, что все будет работать, при загрузке приложения Rails необходимо включить содержимое каталога lib.

config / application.rb

module ApiApp
  class Application < Rails::Application
    #.....
    config.autoload_paths << Rails.root.join('lib')
    #.....
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...