在现有Rails应用程序中创建JSON API

时间:2018-02-05 13:56:09

标签: ruby-on-rails ruby

我正在使用Rails web-app,其中包含将某个文档的请求推送到DB的表单。其他机器上的脚本应该询问新创建的请求。为了解决这个问题,我决定在应用程序中添加小型JSON API。

为了这个目的,我添加了

  defaults format: :json do
    get "/api_name/get_request", to: "api_name#get_request"
  end

之后我遇到了CSRF问题。谷歌搜索后我发现我需要在控制器中添加protect_from_forgery unless: -> { request.format.json? }。它看起来像下面的代码

class ApiNameController < ApplicationController
  protect_from_forgery unless: -> { request.format.json? }

  def get_request
    render json: {message: 'Received'}, status: :ok
  end
end

在日志之后我有

Started GET "/api_name/get_request" for ::1 at 2018-02-05 16:43:08 +0300
Processing by ApiNameController#get_request as JSON
  Parameters: {"api_name"=>{}}
Completed 401 Unauthorized in 5ms (ActiveRecord: 0.0ms)

所以问题仍然存在。问题是

  1. 我该怎么做才能解决问题?
  2. 允许来自任何来源的JSON请求似乎很危险。我该如何提供一些保护?也许我应该从远程机器发送一些标题并在verified_request内查看它?
  3. UPD 我已使用get_requestrender json: {message: 'Received'}, status: :ok内更改了评论,之后结果相同

2 个答案:

答案 0 :(得分:2)

如果在ApplicationController中分配了它,则必须跳过设计before_actions。

<强>控制器:

class ApiController < ApplicationController
   protect_from_forgery unless: -> { request.format.json? }
   skip_before_action :authenticate_user!, only: :get_request

   def get_request
      render json: {message: 'Received'}, status: :ok
   end

end

<强>路线:

namespace :api, defaults: { format: :json } do
   get 'get_request' => 'api#get_request'
end

处理交叉原点:

Rack Cors Gem Link

Rack Attack Gem Link

答案 1 :(得分:1)

您可能在ApplicationController的{​​{1}}中有一些网络身份验证,因为您的before_filter继承了它。这就是您收到ApiNameController回复的原因。所以你应该停止从它继承,或者在某种情况下从web-auth之前排除api控制器方法:

Unauthorized

说到安全性,您至少有两个选择:

最后一个不如基于令牌的身份验证安全,但它更容易实现,因此由您决定选择哪一个。