简体   繁体   中英

Basic authentication not working in node-rest-client node

I'm using node-rest-client library to call my rest API running a python flask app in a test server. The Node setup and request code is below.

If I add a user token to the request header it words fine, but in the call to obtain the user token using basic auth my python system is successfully authenticating and returning the token with a 200 status, but the flask server is then changing this to a 400 Bad Request. It works fine making the call using Postman.

Is there something missing from my two config objects for node-rest-client?

Cheers.

var options_auth = { 
    user: "bob", 
    password: "password",
    mimetypes: {
        json: ["application/json", "application/json;charset=utf-8"]
    } 
};

var Client = require('node-rest-client').Client;
var client = new Client(options_auth);
var method = "/authtoken";

var args = {
    headers: { 
        "Content-Type": "application/json",
        "api-key": "asf89a7assa98d7sd98d98ds",
        //"token": "dsf98s7dsf98dsf7sd98f7dsf",
        "Accept": "application/json"
    },
    responseConfig: {
        timeout: 1000 //response timeout
    }
};

client.get(Api.url+method, args, function (data, response) {
    // parsed response body as js object 
    // raw response 
    //console.log(response);

    if(Buffer.isBuffer(data)){
        data = data.toString('utf8');
    }
    console.log(data);

    var stringData = data.toString('utf8');

    console.log("String data = "+stringData);

}).on('error', function (err) {
    console.error('Something went wrong with the http client', err);
});

Also, spotted these differences between the request headers received by the server:

// Node Request fails: 400
  'headers': EnvironHeaders([
        ('Authorization', u'Basic XXXXXXXXXXXXXX=='),
        ('Vga-Api-Key', u'xxxxxxxxxxxxxxxxxxxxxxxx'),
        ('Content-Length', u'0'), 
        ('Connection', u'close'), 
        ('Host', u'127.0.0.1:8080'), 
        ('Accept', u'*/*'), 
        ('Content-Type', u'application/json')]),

  // Postman Request works: 200
  'headers': EnvironHeaders([
        ('Authorization', u'Basic XXXXXXXXXXXXXX=='), 
        ('Vga-Api-Key', u'xxxxxxxxxxxxxxxxxxxxxxxx'), 
   *    ('Content-Length', u''), 
   *    ('Connection', u'keep-alive'), 
        ('Host', u'127.0.0.1:8080'), 
   *    ('Cache-Control', u'no-cache'), 
        ('Accept', u'*/*'), 
        ('Content-Type', u''), 
   *    ('Accept-Encoding', u'gzip, deflate')]),

The problem is your setting of the header Content-Type: application/json and the probable calling in the server of request.get_json() directly, or indirectly via the (deprecated) request.json property.

When get_json() is called Flask will check to see that a JSON payload has been sent in the body of the request and then parse it if present. That's OK if the request actually contains JSON in the body, but, being a GET request, yours doesn't. In this case, its JSON expectation being unfulfilled, the server raises a BadRequest error and returns a HTTP 400 error response.

From what you've shown your request doesn't need to be JSON because the authorisation username and password are passed in the Authorization: Basic xxxxxxxx header.

The easiest and best way to fix the problem is to simply omit the content type header.

Alternatively you can tell Flask not to complain if there is no JSON data to parse by passing silent=True to get_json , but this just papers over the problem and is not a good idea.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM