1
votes

I'm creating a public, embedded app for Shopify with a simple goal: retrieve a list of products that are out of stock and give the owner the option to delete them. I'm making an API request to find products that are out of stock, which is working fine. Though when I attempt to delete the products, I'm getting 'can't verify CSRF...'

I'm running rails 5.2.3 and ruby 2.5.0 , I've tried using a different version of rails, ensured I have <% csrf meta... %> in my layout, and the app has 'write_products' permissions in the authorization url.

I'm new to rails so I'm hoping this is the result of a simple mistake I'm making.

Here's my routes.rb:

Rails.application.routes.draw do
  root :to => 'home#index'
  mount ShopifyApp::Engine, at: '/'
  post '/destroy', to: 'home#destroy'
end

home_controller :

class HomeController < AuthenticatedController
  def index
    @products = ShopifyAPI::Product.find(:all, params: { limit: 10 })
    @webhooks = ShopifyAPI::Webhook.find(:all)
  end

  def destroy
    params[:product_ids].each do |product_id|
      puts product_id
      ShopifyAPI::Product.delete(product_id)
    end
  end
end

and the HTML form sending the post request:

<form action="destroy" method="post">
<% @products.each do |product| %>
  <% if product.variants.all? { |variant| variant.inventory_quantity == 0 } %>
    <input type="checkbox" name="product_ids[]" value="<%=product.id%>"><%= product.title %></input>
  <% end %>
<% end %>
<button type="submit">delete products</button>
</form>

The form POSTs selected product_id's to the destroy route, which makes an API call to delete each product.

The relevant Heroku logs output is:

2019-06-01T16:47:00.028409+00:00 app[web.1]: I, [2019-06-01T16:47:00.028316 #4]  INFO -- : [f88f9c69-7c6c-4a31-a386-f6916c295700] Started POST "/destroy" for 24.96.97.148 at 2019-06-01 16:47:00 +0000
2019-06-01T16:47:00.029561+00:00 app[web.1]: I, [2019-06-01T16:47:00.029496 #4]  INFO -- : [f88f9c69-7c6c-4a31-a386-f6916c295700] Processing by HomeController#destroy as HTML
2019-06-01T16:47:00.029628+00:00 app[web.1]: I, [2019-06-01T16:47:00.029573 #4]  INFO -- : [f88f9c69-7c6c-4a31-a386-f6916c295700]   Parameters: {"product_ids"=>["1594488094775"]}
2019-06-01T16:47:00.029867+00:00 app[web.1]: W, [2019-06-01T16:47:00.029808 #4]  WARN -- : [f88f9c69-7c6c-4a31-a386-f6916c295700] Can't verify CSRF token authenticity.

EDIT:

I updated my route to : post '/home', to: 'home#destroy'

and used the form_tag method to create my form which added an authentication token to the form:

<%= form_tag(home_path) do %>
<% @products.each do |product| %>
  <% if product.variants.all? { |variant| variant.inventory_quantity == 0 } %>
    <input type="checkbox" name="product_ids[]" value="<%=product.id%>"><%= product.title %></input>
  <% end %>
<% end %>
<button type="submit">delete products</button>
<% end %>
</form>

And it solved my issue.

1

1 Answers

0
votes

I think you forgot the = in your csrf_meta_tag.

<%= csrf_meta_tag %>

The <%= indicates that the output of the command should be printed to the html, while <% is just an operation without printing to the html.