RailsのJWT認証でエラーが発生しました
概要
これは、新しいユーザーを作成するために { http://localhost:3000/users } を押しているときに発生するエラーですが、以下の問題に直面しています。
UsersController#index の JWT::DecodeError Nil JSON Web トークン ソースを抜粋(12行目あたり)
def jwt_decode (token)
decoded = JWT.decode(token, SECRET_KEY)[0]
HashWithIndifferentAccess.new decoded
end
class AuthenticationController < ApplicationController
protect_from_forgery with: :exception
skip_before_action :authenticate_request
# POST /auth/login
def login
@user User.find_by_email (params[:email])
if @user&.authenticate(params[:password])
token = jwt_encode(user_id: @user.id)
render json: { token: token }, status: :ok
else
render json: { error: 'unauthorized' }, status: :unauthorized
end
end
end
class ApplicationController < ActionController::Base
require 'stripe'
Stripe.api_key = 'sk_test_51O1pqnSCcF3F1d0MklDFQ0DIDSQ366PJh3YVx8AEqZH5OYRDjIMKOQdACJ5dxNiMkAH4dZdAZy48yzp6FKS3KMAy00VB8RVFBI'
protect_from_forgery with: :exception
protect_from_forgery with: :null_session
include JsonWebToken
before_action :authenticate_request
private
def authenticate_request
header = request.headers["Authorization"]
header = header.split(" ").last if header
decoded = jwt_decode(header)
@current_user= User.find(decoded[:user_id])
end
end
class UsersController < ApplicationController
protect_from_forgery with: :exception
skip_before_action :authenticate_request, only: [:create]
before_action :set_user, only: [:show, :destroy]
def index
@users = User.all
render json: @users, status: :ok
end
def create
@user = User.new(user_params)
if @user.save
render json: @user, status: :created
else
render json:{ errors: @user.errors.full_messages },
status: :unprocessable_entity
end
end
この問題を解決しようと努力してきましたが、解決できませんでした。
解決策
以下のメソッドをマップしていると思われる GET リクエストを通じて http://localhost:3000/users にアクセスしようとしています。
def index
@users = User.all
render json: @users, status: :ok
end
ApplicationController には before_action :authenticate_request が設定されており、コントローラーのすべてのアクション (メソッド) の前に呼び出されます。したがって、ログインしていない場合はエラーが発生します。
しかし、あなたの質問では、ユーザーを作成しようとしているときにこのエラーが発生していると言っています。つまり、実際には def Index の代わりに def create を呼び出すつもりですよね?
リクエストメソッドのタイプをGETからPOSTに変更してみてはいかがでしょうか?ルートが分からないので推測に基づいて話しています。
POST http://localhost:3000/users