craig
craig

Reputation: 26262

Node https request returns Missing or duplicate parameters

Trying to get a token from ADP's API.

const https = require('https')
const fs = require('fs')
require('dotenv').config()

var requestBody = JSON.stringify({
    client_id: process.env.ADP_CLIENT_ID,
    client_secret: process.env.ADP_CLIENT_SECRET,
    grant_type: 'client_credentials',
});

const options = {
    hostname: 'accounts.adp.com',
    port: 443,
    path: '/auth/oauth/v2/token',
    method: 'POST',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': requestBody.length
    },
    cert: fs.readFileSync('certificate.pem'),
    key: fs.readFileSync('private.key'),
    agent: false,
}
console.debug(options)

const req = https.request(options, (res) => {
    let response = ''

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

    res.on('data', (chunk) => {
        response += chunk
    })
    res.on('end', ()=>{
        console.log('Body: ', JSON.parse(response));
    })
}).on("error", (err) => {
    console.error("Error: ", err.message);
});
        
req.write(requestBody)
req.end()

When the script runs, an error is returned from the service:

$ node ./get_token.js
{
  hostname: 'accounts.adp.com',
  port: 443,
  path: '/auth/oauth/v2/token',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': 141
  },
  cert: <Buffer ... bytes>,
  key: <Buffer ... bytes>,
  agent: false
}
statusCode: 400
headers: {
  'adp-correlationid': 'XXX',
  'x-ca-err': '3003103',
  'cache-control': 'no-store',
  pragma: 'no-cache',
  'content-type': 'application/json;charset=UTF-8',
  'content-length': '84',
  date: 'Wed, 18 Jan 2023 17:50:06 GMT',
  connection: 'close',
  server: 'ADP API'
}
body:  {
  error: 'invalid_request',
  error_description: 'Missing or duplicate parameters'
}

What am I missing or duplicating?

Upvotes: 1

Views: 109

Answers (1)

craig
craig

Reputation: 26262

I needed to correctly serialize the requestBody:

...
const qs = require('querystring');

...

var requestBody = qs.stringify({
    client_id: process.env.ADP_CLIENT_ID,
    client_secret: process.env.ADP_CLIENT_SECRET,
    grant_type: 'client_credentials',
});

which generated the expected response:

{
  access_token: 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
  token_type: 'Bearer',
  expires_in: 3600,
  scope: 'api'
}

Upvotes: 1

Related Questions