通过 ActionCable 插入的表单无法验证

MCB*_*MCB 5 forms ruby-on-rails csrf actioncable

我有一个设置,用户 A 拒绝用户 B 的提议。这会触发 ActionCable 将使用创建的表单推button_to送给用户 B,通知他这一点,然后让他单击该消息将其删除。但表格提出了ActionController::InvalidAuthenticityToken

params {"_method"=>"delete", "authenticity_token"=>"4lqu8...", "id"=>"31"}

我确实有另一种表单,我使用 ActionCable 将create表单替换为update表单,并且工作正常。因此,我尝试将流程更改为当用户 A 拒绝报价时,它会触发用户 B 请求消息。为此,我将逻辑从服务对象移至

class AuctionOwnChannel < ApplicationCable::Channel
  def subscribed
    #...
  end

  def display(hash)
    ActionCable.server.broadcast "auction_own_channel_#{params[:oPId]}_#{current_user.id}", hash
  end

  # In the code below `rack_inputs` is passed into `frustrated_replacement` and the subsequent methods to reach `render`
  def rejected(data)
    info = data["info"]
    display BidServices::Process.frustrated_replacement(info["product_id"], info["message_id"], current_user)
  end
end

module BidServices
  class Process
    class << self
      def frustrated_replacement(product_id, message_id, user)
        message = Message.find message_id
        thing = {partial: "messages/rejected", locals: {message: message}}
        replacements(thing, user)
      end

      def replacements(thing, user)
        { processed_bid: render(thing),
          cart: render(partial: "bids/cart", locals: {current_user: user} )
        }
      end

      def render(*args)
        a_c = ApplicationController
        a_c.per_form_csrf_tokens = true # Have tried with and without this
        a_c.renderer.render(*args)
      end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

编辑:自从写这篇文章以来,我做了进一步的研究并浏览了 ActionView 的一些代码,我认为我需要设置会话

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user, :rack_inputs

    def connect
      self.rack_inputs  = find_rack_inputs
      self.current_user = find_verified_user
      logger.add_tags 'ActionCable', current_user.id
    end

    protected
    def find_rack_inputs
      # I just tried adding `session` in the hash but it did not help
      {input: env["rack.input"], http_host: env['HTTP_HOST'], session: env["rack.session"]} 
    end

   # Attempt to replace whole env
   # def find_rack_inputs
      # env 
   # end
  end
end


module BidServices
  class Process
      def render(*args)
        rack_inputs = args.pop
        controller = MessagesController
        renderer = controller.renderer.new(rack_inputs)
        renderer.render(*args)
      end

      # The changes when I was replacing the env
      # def render(*args)
      #   rack_inputs = args.pop # This attempt rack_inputs was `env`
      #   MessagesController.renderer.new(rack_inputs).render(*args)
      # end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)