# Improve BAD CSRF error message when making API calls with content-type application/json

**URL:** https://meta.discourse.org/t/improve-bad-csrf-error-message-when-making-api-calls-with-content-type-application-json/117136
**Category:** Development
**Created:** [May 8, 2019, 1:14am UTC](https://meta.discourse.org/t/improve-bad-csrf-error-message-when-making-api-calls-with-content-type-application-json/117136 "2019-05-08T01:14:42Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [May 8, 2019, 1:14am UTC](https://meta.discourse.org/t/improve-bad-csrf-error-message-when-making-api-calls-with-content-type-application-json/117136/1 "2019-05-08T01:14:42Z")

</div>

API requests with the Content-Type as “application/json” often receive an unhelpful message like “BAD CSRF”, so we should improve the error messaging so that it provides more details as to why they are receiving this error message.

---

<div class="post-metadata">

### Author: ![ChrisBeach](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/chrisbeach/32/214628_2.png) [@ChrisBeach](https://meta.discourse.org/u/ChrisBeach)
#### Post date: [May 12, 2019, 8:32pm UTC](https://meta.discourse.org/t/improve-bad-csrf-error-message-when-making-api-calls-with-content-type-application-json/117136/3 "2019-05-12T20:32:21Z")

</div>

Hi Blake,

I’ve been sending JSON payloads to the API and up until recently, I’ve received a JSON response.

Whilst my calls to the API still seem to work correctly (i.e. a topic is created when I post to `posts.json`), the response now comes back as `null` (rather than the json I used to receive) and this breaks my response parsing.

In the Rails log I see

```plaintext
Started POST "/posts.json" for 82.44.224.199 at 2019-05-12 20:16:32 +0000
Processing by PostsController#create as JSON
  Parameters: {"title"=>"RT @love_se4: One of those hidden gems in the local community, you just have to try. Over 170 different gins. Proper mixologists who know h…", "raw"=>"https://twitter.com/se23_tweets/status/1127663613412630529", "category"=>49, "post"=>{"raw"=>"https://twitter.com/se23_tweets/status/1127663613412630529"}}
Can't verify CSRF token authenticity.
Completed 200 OK in 9ms (Views: 0.2ms | ActiveRecord: 0.0ms)

```

I’ve tried sending the API keys in the query string and in the HTTP headers. Seems they’re being accepted by the remote side.

I want to send data to Discourse in JSON form rather than form encoded. JSON worked in the past. Is there anything I can do to restore the functionality of my API code?

---

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [May 13, 2019, 7:10pm UTC](https://meta.discourse.org/t/improve-bad-csrf-error-message-when-making-api-calls-with-content-type-application-json/117136/4 "2019-05-13T19:10:21Z")

</div>

Can you share with me your actual ruby code to make this request? I’m unable to reproduce this locally. Here is the Postman json call I’m making and I’m always getting a response back:

 ![image](https://global.discourse-cdn.com/meta/original/3X/0/f/0f3b7a1508e31a50bd1c6fac36fb37efb1eba58f.png)

 ![image](https://global.discourse-cdn.com/meta/original/3X/1/c/1c33179e45605bb34c4ea92e199b2f37144643ab.png)

Also I don’t think you need the extra `post["raw"]` parameter.

`Parameters: {"title"=>"RT @love_se4: One of those hidden gems in the local community, you just have to try. Over 170 different gins. Proper mixologists who know h…", "raw"=>"https://twitter.com/se23_tweets/status/1127663613412630529", "category"=>49, "post"=>{"raw"=>"https://twitter.com/se23_tweets/status/1127663613412630529"}}`

---

<div class="post-metadata">

### Author: ![blake](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/blake/32/157322_2.png) [@blake](https://meta.discourse.org/u/blake)
#### Post date: [June 21, 2019, 8:28pm UTC](https://meta.discourse.org/t/improve-bad-csrf-error-message-when-making-api-calls-with-content-type-application-json/117136/5 "2019-06-21T20:28:56Z")

</div>

I’m unassigning myself from this for now, but would like to leave it open as a place to track any future “BAD CSRF” errors in case they continue to occur.

From digging into this I realized that most of the BAD CSRF errors came from before we [switched to header based authentication](https://meta.discourse.org/t/discourse-2-3-0-beta4-release-notes/111296) via the API.

Pre-header based auth, if the json request was malformed in some way we couldn’t read the `API_KEY` out of the paremeters and so we couldn’t detect if the request was an actual API request on [this line](https://github.com/discourse/discourse/blob/master/app/controllers/application_controller.rb#L38) in the application controller:

```
unless is_api? || is_user_api?

```

and so we would just return:

```
  render plain: "[\"BAD CSRF\"]", status: 403

```

But now that API credentials are almost always in the HTTP Header of the request we can determine that the request is actually an API request with much better accuracy than before and so the “BAD CSRF” error shouldn’t show up as frequently anymore.

---

<div class="post-metadata">

### Author: ![nylen](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/nylen/32/125684_2.png) [@nylen](https://meta.discourse.org/u/nylen)
#### Post date: [September 14, 2020, 7:13pm UTC](https://meta.discourse.org/t/improve-bad-csrf-error-message-when-making-api-calls-with-content-type-application-json/117136/8 "2020-09-14T19:13:10Z")

</div>

We were seeing this error after a recent Discourse upgrade (within the last few months). The application was not authenticating against the API via the HTTP headers, changed it to do so and now it works again.
