I have a Rails 5 API app (ApplicationController < ActionController::API
). The need came up to add a simple GUI form for one endpoint of this API.
Initially, I was getting ActionView::Template::Error undefined method protect_against_forgery?
when I tried to render the form. I added include ActionController::RequestForgeryProtection
and protect_from_forgery with:exception
to that endpoint. Which solved that issue as expected.
However, when I try to submit this form I get: 422
Unprocessable Entity
ActionController::InvalidAuthenticityToken
. I've added <%= csrf_meta_tags %>
and verified that meta: csrf-param
and meta: csrf-token
are present in my headers, and that authenticity_token
is present in my form. (The tokens themselves are different from each other.)
I've tried, protect_from_forgery prepend: true, with:exception
, no effect. I can "fix" this issue by commenting out: protect_from_forgery with:exception
. But my understanding is that that is turning off CSRF protection on my form. (I want CSRF protection.)
What am I missing?
UPDATE:
To try to make this clear, 99% of this app is a pure JSON RESTful API. The need came up to add one HTML view and form to this app. So for one Controller I want to enable full CSRF protection. The rest of the app doesn't need CSRF and can remain unchanged.
UPDATE 2:
I just compared the page source of this app's HTML form and Header with another conventional Rails 5 app I wrote. The authenticity_token
in the Header and the authenticity_token
in the form are the same. In the API app I'm having the problem with, they're different. Maybe that's something?
UPDATE 3:
Ok, I don't the the mismatch is the issue. However, in further comparisons between the working and non-working apps I noticed that there's nothing in Network > Cookies. I see a bunch of things like _my_app-session
in the cookies of the working app.