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
3 Réponses :
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
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
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