Reputation: 29
I follow tutorial from https://www.pluralsight.com/guides/token-based-authentication-with-ruby-on-rails-5-api with some fixed error its running well..
but after i deploy to heroku, When i want to access authenticate route (sign in user), i got status code 500 in insomia :
{
"status": 500,
"error": "Internal Server Error"
}
and in terminal i got this code :
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'
here my 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
here my 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
here 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
I have set the environment variable RAILS_MASTER_KEY, to my heroku with the same value as the contents of config / master.key : my heroku config var
my 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]
Thanks in advance
EDIT:
here my 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
Upvotes: 2
Views: 960
Reputation: 605
I have followed the same blog, but when I place my code after the class header, it just works !!!
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
Upvotes: 0
Reputation: 29
SOLUTION :
Change my config/application.rb from
module RubyChallenge
class Application < Rails::Application
...
config.autoload_paths << Rails.root.join('lib')
...
end
end
to
module RubyChallenge
class Application < Rails::Application
...
config.eager_load_paths << Rails.root.join('lib')
...
end
end
make it runing well, it because Rails 5 disables autoloading after booting the app in production, thx to Shailesh Kalamkar Article
Upvotes: 0
Reputation: 6531
Probably you are missing this: -
By default any file in app directory is auto loaded and you can use it without including it, However outside this you would have to load it when application is loaded.
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
Upvotes: 1