Creating a topic via the API using Node.js

I am trying to create a new topic via Node.js API by sending the following payload :

 { title: 'topic:329201',
  raw: 'topic-description:32920111948',
  created_at: '2019-05-08',
  api_key:
   '2371b6549b0c3aeb1f12e49c22db5f25fb1f8ca740619e5304f12f4d29896097',
  api_username: 'cb1' 
}

I am hitting the API via HTTP module of node with the following options :

{ host: '13.127.14.24',
  port: '3000',
  path: '/posts',
  method: 'POST',
  headers:
   { 'content-type': 'application/x-www-form-urlencoded',
     'content-length': 194,
     Accept: '*/*',
     Connection: 'keep-alive' }
 }

But I am getting [ā€œBAD CSRFā€] in body. Can anyone help.

You should probably revoke that API key since you just posted it :wink:

This is usually because incorrect content-type encoding was specified in the request.

1 Like

Donā€™t worry dude. I am smart enough to randomly change some characters in it.
And can you specify what i should send in ā€˜content-typeā€™, as Iā€™ve tried a lot of things.

2 Likes

Its neither working with Content-Type:application/x-www-form-urlencoded nor with ā€˜content-typeā€™:ā€˜application/jsonā€™.

You will tend to get ā€œBAD CSRFā€ if your api key has not been supplied correctly. The best way to send it is via HTTP headers. There are more details at the top of our api documentation.

4 Likes

You might need to have correct capitalization for your header keys. So ā€˜content-typeā€™ needs to be changed to ā€˜Content-Typeā€™. Same for ā€˜Content-Lengthā€™, but you probably donā€™t even need to specify that one.

1 Like

Fwiw: HTTP header names are (should be) case insensitive per RFC2616 4.2.

1 Like

Problem solved. Thanks to @david. I was sending api_key in the payload but needed to send it via HTTP headers. I owe you a Beer. :laughing:

2 Likes

Ohh good, glad you got it working! Yes, sending them in the HTTP headers is the correct way to do it now, but they should still work in the body of the POST. Because Iā€™m trying to improve our error messaging when using the API is there anything you changed as well? Also would you be willing to share the actual node http request code? And how are you using something like querystring.stringify on your payload? Thanks!

5 Likes

Vishal, would you mind sharing the Node code youā€™re using to make this request?

Iā€™m stuck with a 404 error, no matter what I try.

@souljacker Sorry for the late reply. Were you able to get it working?

Blake do you have someone on your engineering team who would also guide me how to make the same request with Node.js. Can talk via DM if you donā€™t want to post that in this Python thread. Thanks a lot!

Iā€™ve adapted the example from the node.js website to demo how to send a POST request to discourse using node.js:

const http = require('http');
const crypto = require('crypto');
const querystring = require('querystring');

const title = crypto.randomBytes(6).toString("hex") + ' ' + crypto.randomBytes(3).toString("hex") + ' ' + crypto.randomBytes(4).toString("hex");
const raw = crypto.randomBytes(16).toString("hex") + ' ' + crypto.randomBytes(16).toString("hex") + ' ' + crypto.randomBytes(16).toString("hex");

const api_key = 'f2b43adc...';
const api_username = 'system';

var data = {
  title: title,
  raw: raw
};

data = JSON.stringify(data);

const options = {
  hostname: 'localhost',
  port: 3000,
  path: '/posts',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length,
    'Api-Key': api_key,
    'Api-Username': api_username
  }
};

const req = http.request(options, (res) => {
  console.log(`statusCode: ${res.statusCode}`)

  res.on('data', (d) => {
    process.stdout.write(d)
  })
});

req.on('error', (error) => {
  console.error(error)
});

req.write(data);
req.end();

4 Likes