Rails API ActiveStorage DirectUpload产生422错误InvalidAuthenticityToken

时间:2019-05-09 21:09:38

标签: ruby-on-rails reactjs rails-activestorage

Rails API应用程序活动存储有问题。我有React,我想从那里上传文件。

   TableRow row = new TableRow();

   table.Rows.Add(row);
   table.Rows.Add(row);
   table.Rows.Add(row);

但是在提交时,我遇到了错误import React from "react"; import {DirectUpload} from "activestorage"; class SignIn extends React.Component { constructor(props) { super(props); this.state = { file: null }; this.handleFileChange = this.handleFileChange.bind(this); this.handleFileSubmit = this.handleFileSubmit.bind(this); } handleFileChange(e){ this.setState({file: e.target.files[0]}) } handleFileSubmit(){ const upload = new DirectUpload(this.state.file, "/rails/active_storage/direct_uploads"); upload.create((error, blob) => { if(error){ console.log(error) } else { console.log(blob) } }) } render() { return ( <React.Fragment> <Form> <Form.Item> <Input type="file" onChange={this.handleFileChange}/> </Form.Item> <Form.Item> <Button type="primary" htmlType="submit"> Register </Button> </Form.Item> </Form> </React.Fragment> ); } }

Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms)

我在application_controller.rb Started POST "/rails/active_storage/direct_uploads" for 127.0.0.1 at 2019-05-09 22:59:54 +0200 Processing by ActiveStorage::DirectUploadsController#create as JSON Parameters: {"blob"=>{"filename"=>"file.jpg", "content_type"=>"image/jpeg", "byte_size"=>27095, "checksum"=>"8u95dXg39vap1Cq/2fgfbg=="}, "direct_upload"=>{"blob"=>{"filename"=>"file.jpg", "content_type"=>"image/jpeg", "byte_size"=>27095, "checksum"=>"8u95dXg39vap1Cq/2fgfbg=="}}} Can't verify CSRF token authenticity. Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms) ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken): actionpack (5.2.3) lib/action_controller/metal/request_forgery_protection.rb:211:in `handle_unverified_request' actionpack (5.2.3) lib/action_controller/metal/request_forgery_protection.rb:243:in `handle_unverified_request' devise (4.6.2) lib/devise/controllers/helpers.rb:255:in `handle_unverified_request' actionpack (5.2.3) lib/action_controller/metal/request_forgery_protection.rb:238:in `verify_authenticity_token' activesupport (5.2.3) lib/active_support/callbacks.rb:426:in `block in make_lambda' activesupport (5.2.3) lib/active_support/callbacks.rb:198:in `block (2 levels) in halting' actionpack (5.2.3) lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>' activesupport (5.2.3) lib/active_support/callbacks.rb:199:in `block in halting' activesupport (5.2.3) lib/active_support/callbacks.rb:513:in `block in invoke_before' 中进行了设置,但仍然出现错误。

2 个答案:

答案 0 :(得分:0)

我有同样的问题。解决此问题的两种方法:

1。猴子补丁(不推荐)

config/initializers/direct_uploads.rb中:

require 'active_storage/direct_uploads_controller'

class ActiveStorage::DirectUploadsController
  protect_from_forgery with: :null_session
end

2。自定义控制器(推荐)

假设您拥有/api/v1的API端点:

config/routes.rb

namespace :api do
  scope module: 'v1', path: 'v1' do
    resources :direct_uploads, only: [:create]
  end
end

app/controllers/api/v1/direct_uploads_controller.rb

class Api::V1::DirectUploadsController < ActiveStorage::DirectUploadsController
  # Should only allow null_session in API context, so request is JSON format
  protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }

  # Also, since authenticity verification by cookie is disabled, you should implement you own logic :
  before_action :verify_user

  private

  def verify_user
    raise unless User.find(doorkeeper_token[:resource_owner_id])
  end
end

并使用正确的端点更改DirectUpload实例:

const upload = new DirectUpload(this.state.file, "/api/v1/direct_uploads");

希望这会有所帮助。干杯!

答案 1 :(得分:0)

使用带有 skip_forgery_protection 的自定义控制器在仅 API 模式下禁用伪造保护。

# app/controllers/api/v1/direct_uploads_controller.rb
class Api::V1::DirectUploadsController < ActiveStorage::DirectUploadsController
  skip_forgery_protection
end