Проблемы с доступом к текущему пользователю в Rails 5.2 api controller - PullRequest
0 голосов
/ 27 мая 2019

У меня есть серверная часть Rails 5.2 только для api, использующая для аутентификации jwt, и я пытаюсь реализовать голосование с помощью гема act_as_votable. положительные голоса записываются, как и ожидалось, если я жестко закодировал переменную @current_user в действии контроллера. Однако при практическом использовании это не сработает.

вот мой authentic_controller.rb:

  before_action :authorize_request, except: :login

  # POST /auth/login
  def login
    @user = User.find_by_email(params[:email])
    if @user&.authenticate(params[:password])
      token = JsonWebToken.encode(user_id: @user.id)
      time = Time.now + 24.hours.to_i
      render json: { token: token, exp: time.strftime("%m-%d-%Y %H:%M"),
                     username: @user.username }, status: :ok
    else
      render json: { error: 'unauthorized' }, status: :unauthorized
    end
  end

  private

  def login_params
    params.permit(:email, :password)
  end

end```

my application_controller.rb:

```class ApplicationController < ActionController::API

  def not_found
    render json: { error: 'not_found' }
  end

  def authorize_request
    header = request.headers['Authorization']
    header = header.split(' ').last if header
    begin
      @decoded = JsonWebToken.decode(header)
      @current_user = User.find(@decoded[:user_id])
    rescue ActiveRecord::RecordNotFound => e
      render json: { errors: e.message }, status: :unauthorized
    rescue JWT::DecodeError => e
      render json: { errors: e.message }, status: :unauthorized
    end
  end

  private

end```

and my upvote method in the [model_name]_controller.rb:

```module Api
  module V1
    class ModelNamesController < ApplicationController
      before_action :authorize_request, except: [:show, :index, :upvote, :downvote]
      before_action :set_model_name, only: [:show, :update, :destroy, :upvote, :downvote]

      ...

      def upvote
        @decoded = JsonWebToken.decode(header)
        @current_user = User.find(@decoded[:user_id])
        @model_name.upvote_from @current_user
        render layout: false
      end

      ...

      private
        # Use callbacks to share common setup or constraints between actions.
        def set_model_name
          @model_name = ModelName.find(params[:id])
        end

       ...
  end
end```

routes.rb:

```Rails.application.routes.draw do

  namespace :api do
    namespace :v1 do
      resources :[model_name]s do
        member do
          put "upvote" => "[model_name]s#upvote"
          put "downvote" => "[model_name]s#downvote"
        end
      end
    end
  end

  root to: "[model_name]s#index"

  resources :users, param: :_username
  post '/auth/login', to: 'authentication#login'

end```

I am using Postman to do a PUT request to localhost/api/v1/[model_name]s/1/upvote. when @current user is set manually to User.find(1), votes are recorded.

However, logging in to Postman as User.find(3), i get no error

```I, [2019-05-27 10:53:06#64097]  INFO -- : Started PUT "/api/v1/model_names/1/upvote" for ::1 at 2019-05-27 10:53:06 -0400
I, [2019-05-27 10:53:06#64097]  INFO -- : Processing by Api::V1::ModelNamesController#upvote as */*
I, [2019-05-27 10:53:06#64097]  INFO -- :   Parameters: {"email"=>"user3@gmail.com", "password"=>"[FILTERED]", "id"=>"1", "model_name"=>{}}
D, [2019-05-27 10:53:06#64097] DEBUG -- :   ModelName Load (0.6ms)  SELECT  "model_names".* FROM "model_names" WHERE "model_names"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
D, [2019-05-27 10:53:06#64097] DEBUG -- :   ↳ app/controllers/api/v1/model_names_controller.rb:57
I, [2019-05-27 10:53:06#64097]  INFO -- : Completed 200 OK in 60ms (Views: 0.1ms | ActiveRecord: 8.3ms)``` 

but votes are not recorded.
...