405 Not Allowed using secret REST from Nginx

Just migrated to tgcloud 3.5.3.
I’m calling getToken from nodeJS and the tgcloud server returns 405 Not Allowed error.

The calling user (mor) is an Admin on the graph DB:

I’m passing a secret I have defined (the second one):

This is my JS code sent from my local machine over nodeJS:


exports.getToken = (secret, domain = "localhost", lifetime = 1000000, callback = (ans) => { console.log(ans); }) => {

  var url = "https://" + domain + ".i.tgcloud.io";

  var data = {

    "secret": secret,

    "lifetime": lifetime

  };

  const options = {

    url: url,

    port: 9000,

    path: '/requesttoken',

    method: 'POST',

    json: true,

    body: data

  };

  request(options, function (err, res, body) {

    if (err) {

      console.error('error requesting tgGraphDB: ', err);

      throw err;

    }

    var headers = res.headers;

    var statusCode = res.statusCode;

    console.log('headers: ', headers);

    console.log('statusCode: ', statusCode);

    console.log('body: ', body);

    return callback(JSON.parse(body)["token"]);

  })

}```

And this is what's coming back:

```headers:  {
  server: 'nginx',
  date: 'Thu, 02 Jun 2022 10:00:07 GMT',
  'content-type': 'text/html',
  'content-length': '150',
  connection: 'close',
  'access-control-allow-origin': '*',
  'x-frame-options': 'SAMEORIGIN'
}
statusCode:  405
body:  <html>
<head><title>405 Not Allowed</title></head>
<body>
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx</center>
</body>
</html>```

What am I missing?

Hey!

I got the same error when running your code. For some reason, after modifying it to add the port and path directly with the URL, it worked fine for me.

exports.getToken = (secret, domain = "localhost", lifetime = 1000000, callback = (ans) => { console.log(ans); }) => {

    var url = "https://" + domain + ".i.tgcloud.io:9000/requesttoken"; // Adding the path and port
  
    var data = {
      "secret": secret,
      "lifetime": lifetime
    };
  
    const options = {
      url: url,
      method: 'POST',
      json: true,
      body: data
    };
  
    request(options, function (err, res, body) {
  
      if (err) {
        console.error('error requesting tgGraphDB: ', err);
        throw err;
      }
  
      var headers = res.headers;
      var statusCode = res.statusCode;

      console.log('headers: ', headers);
      console.log('statusCode: ', statusCode);
      console.log('body: ', body);

      return callback(body["token"]); // Returning the token
  
    })
  
  }

Besides shifting the port and path from options to the URL, I also changed the callback to body["token"] since body is already an object.

Once again, I am not completely sure why one version worked and the other did not since they theoretically appear equivalent; I’ll look into that for you. However, let me know if these modifications allow the code to run successfully on your end!

3 Likes

Hey Shreya,
Many thanks!
Work on my end as well now :slight_smile:

I now also got it to work using the https library instead of the request library:

const https = require("https");

exports.getToken = (secret, domain = "localhost", lifetime = 1000000, callback = (ans) => { console.log(ans); }) => {

  var url = domain + ".i.tgcloud.io"; // Adding the path and port

  var data = JSON.stringify({
    "secret": secret,
    "lifetime": lifetime
  });

  const options = {
    hostname: url,
    method: 'POST',
    port: 9000,
    path: "/requesttoken",
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': Buffer.byteLength(data)
      }
  };

  const req = https.request(options, res => {
    var str = '';

    res.on('data', body => {
      str+=body;
      });

    res.on('end',function(){
      console.log('returned data: ', str);
      obj=JSON.parse(str);
      return callback(obj["token"]);
    });
      
      
    req.on('error', error => {
      console.error('Tigergraph token request error: ', error);
    });
      
    });
      req.write(data);
      req.end();

}
3 Likes