2
votes

Rails 5.2.2 Heroku renvoie toujours l'application [web.1]: FATAL - NameError (constante non initialisée AuthenticateUser :: JsonWebToken)

Je suis le tutoriel de https : //www.pluralsight.com/guides/token-based-authentication-with-ruby-on-rails-5-api avec une erreur corrigée, il fonctionne bien ..

mais après le déploiement sur heroku , Lorsque je veux accéder à la route d'authentification (utilisateur de connexion), j'ai le code d'état 500 en insomia:

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

et dans le terminal j'ai obtenu ce code:

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]

voici mon authentication_controller:

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

ici mon 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

ici json_web_token:

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

J'ai défini la variable d'environnement RAILS_MASTER_KEY, sur mon heroku avec la même valeur que le contenu de config / master.key: my heroku config var

mon Gemfile:

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'

Merci d'avance

EDIT:

voici mon config / application.rb:

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

btw merci Mr.Gabbar pour votre suggestion


0 commentaires

3 Réponses :


1
votes

Il vous manque probablement ceci: -

Par défaut, tout fichier dans le répertoire de l'application est automatiquement chargé et vous pouvez l'utiliser sans l'inclure, mais en dehors de cela, vous devrez le charger lorsque l'application est chargée.

Pour vous assurer que tout fonctionnera, le contenu du répertoire lib doivent être inclus lors du chargement de l'application Rails.

config/application.rb

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


0 commentaires

0
votes

SOLUTION:

Changer mon config / application.rb de

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

à

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

le faire fonctionner correctement, car Rails 5 désactive le chargement automatique après le démarrage de l'application en production, merci à Shailesh Kalamkar Article


0 commentaires

0
votes

J'ai suivi le même blog, mais quand je place mon code après l'en-tête de la classe, ça marche juste !!!

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


0 commentaires