Я следую учебнику от https://www.pluralsight.com/guides/token-based-authentication-with-ruby-on-rails-5-api с некоторой исправленной ошибкой, он работает хорошо.
но после развертывания на героку, когда я хочу получить доступ к маршруту аутентификации (войти в систему), я получил код состояния 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"=>"[email protected]", "password"=>"[FILTERED]", "authentication"=>{"email"=>"[email protected]", "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` = '[email protected]' 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_controller:
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здесь мой authentication_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: мой конфиг героку var
мой гемфайл:
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]заранее спасибо
Обновлено:
вот мой конфиг/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




Возможно, вам не хватает этого: -
По умолчанию любой файл в каталоге приложения загружается автоматически, и вы можете использовать его, не включая его, однако вне этого вам придется загружать его при загрузке приложения.
To make sure everything will work, the contents of the lib directory have to be included when the Rails application loads.
config/application.rb
module ApiApp
class Application < Rails::Application
#.....
config.autoload_paths << Rails.root.join('lib')
#.....
end
end
РЕШЕНИЕ :
Измените мой 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 отключает автозагрузку после загрузки приложения в рабочей среде, спасибо Шайлешу Каламкару Статья
Я следил за тем же блогом, но когда я помещаю свой код после заголовка класса, он просто работает!!!
module TodoApiApp
class Application < Rails::Application
config.eager_load_paths << Rails.root.join('lib')
config.load_defaults 5.2
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: %i[get post delete put patch options]
end
end
config.api_only = true
end
end