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