0

My setup is Rails back-end and React front-end. I'm still in local dev just learning basics.

Aside from the initial rendering of the #index or #show actions via Rails, the React front-end accesses resources via localhost:3000/api and is essentially a really simple SPA.

I am including the CSRF token via document.querySelector('meta[name="csrf-token"]').content; and attaching it to the axios headers.

The puzzling thing is that CSRF authentication works totally fine for PUT and POST, but does not work for DELETE. I can't grok why it would work for certain actions but not for others...

Note: I've tested adding random characters to the token for PUT and POST, and CSRF breaks as expected. So I'm fairly sure it's actually doing its job.

I am working with a simple set of resources -- Meetings and Agenda Items.

The JS:

 const handleRemoveAgendaItem = React.useCallback((item) => {
    const token = document.querySelector('meta[name="csrf-token"]').content;
    const url = API_BASE + `/agenda_items/${item.id}`;

    axios
      .delete(url, item, {
        headers: {
          'X-CSRF-TOKEN': token,
          'Content-Type': 'application/json'
        }
      })
      .then(result => {
      });
  });

The Rails controller

class Api::AgendaItemsController < ApplicationController
  def destroy
    @agenda_item = AgendaItem.find(params[:id])
    @agenda_item.destroy
  end
end

The error:

20:20:05 web.1       | Started DELETE "/api/agenda_items/2" for ::1 at 2021-05-05 20:20:05 -0700
20:20:05 web.1       | Processing by Api::AgendaItemsController#destroy as JSON
20:20:05 web.1       |   Parameters: {"id"=>"2"}
20:20:05 web.1       | Can't verify CSRF token authenticity.
20:20:05 web.1       | Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 611)
20:20:05 web.1       | 
20:20:05 web.1       | 
20:20:05 web.1       |   
20:20:05 web.1       | ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
20:20:05 web.1       |   
20:20:05 web.1       | actionpack (6.1.3.1) lib/action_controller/metal/request_forgery_protection.rb:211:in `handle_unverified_request'
20:20:05 web.1       | actionpack (6.1.3.1) lib/action_controller/metal/request_forgery_protection.rb:243:in `handle_unverified_request'
20:20:05 web.1       | actionpack (6.1.3.1) lib/action_controller/metal/request_forgery_protection.rb:238:in `verify_authenticity_token'
dopster
  • 65
  • 1
  • 7
  • AFAIK it's `X-CSRF-Token` not `X-CSRF-TOKEN`. If it's works I'll post a detailed answer. – razvans May 06 '21 at 06:15
  • @razvans just tested -- works both ways for my PUT and POST. DELETE still does not work in either formatting. – dopster May 06 '21 at 16:46
  • An update -- I don't get a CSRF authentication issue if I use Javascript's native fetch API. So it's an axios-specific issue with the DELETE for some reason in my implementation. – dopster May 06 '21 at 18:07
  • Check https://stackoverflow.com/questions/51069552/axios-delete-request-with-body-and-headers. I have the headers added in `axios.create(...)` and it works. – razvans May 06 '21 at 20:30

0 Answers0