I thought that I would share this to hopefully help others after I lost about 4 hours on this during the course of today!
I have been experimenting with creating a simple Web API using Ruby on Rails 5 to give me a common backend for something that I am trying to get working. I have been following the excellent tutorials provided at: https://railstutorial.org and that has helped me get some of the fundamentals working. However, as is typical, I was trying to find some shortcuts to getting the API and JSON particularly up and running so that I could consume it in Swift. To that end I found a very good tutorial on YouTube by Traversy Media that gave me some really good clues.
It also gave me a major hint that I missed completely.
rails new (site) --api
This gives you all the functionality to create an API based application without all of the rest of the heavy lifting.
What it also does is remove the reliance on the Cross-Site Request Forgery token!
There was a very useful recommendation in the video to run Postman in Chrome to help prove that the API works. In the video all worked wonderfully.
Unfortunately, for me all I seemed to ever get was a 422 error.
I couldn’t tell if this was due to the platform that I am using Heroku to deploy to ‘production’.
The in the cloud IDE that I am using Cloud9Â or just my lack of full understanding of Ruby on Rails.
No matter what I tried I was getting the 422 error.
I tried various versions of JSON. Sometimes I’d get a 400 error and sometimes a 500 error…
I watched the video through a number of times…
I then built some messages directly in my Swift code and fired those at the API.
This time the log on Heroku finally said something about the CSRF token and from there I managed to google and found this on StackOverflow
This gave me the information that I needed and I realised that I needed to add the following to my ApplicationController
protect_from_forgery with: :null_session
As this is designed to prevent Cross-site Request forgery, but as the bit that I was building was pure API, although I want some of the rest for testing, then maybe the --api option wouldn’t have been the right one!
I can now run full CRUD operations either from my iOS app or from Postman. So I can continue the experimentation.