Techioz Blog

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