How to get a Token API with fetch - javascript

I have to get a token from an url for an API of "ile de France mobilité", I'm using Fetch and I don't understand how to do this. This is my actual code :
var client_id = "(my client_id)";
var client_secret = "(my client_secret)";
// var url_get = "https://traffic.api.iledefrance-mobilites.fr/v1/tr-global/estimated-timetable";
var grant_type = 'client_credentials'
var token_url = 'https://as.api.iledefrance-mobilites.fr/api/oauth/token'
var scope = 'read-data'
const options = {
method: 'POST',
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
},
body: {
grant_type: grant_type,
client_id: client_id,
client_secret: client_secret,
scope: scope
}
}
const fetch_response = await fetch(token_url, options)
const json = await fetch_response
console.log(json)
response.json(json)
And for answer I have
'Other stuf and :'
[Symbol(Response internals)]: {
url: 'https://as.api.iledefrance-mobilites.fr/api/oauth/token',
status: 401,
statusText: 'Unauthorized',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
}
Does someone know how to do this ?
In my index.html i call this script:
async function asyncCall() {
const api_url = `/trajet`
const response = await fetch(api_url, {method: 'POST'})
const json = await response
//console.log(json)
}
asyncCall()
server:
const app = express()
app.listen(3000, () => console.log('listening at 3000'))
app.use(express.static('public'))
app.use(express.json())
app.use(bodyParser.json())

HTTP Status Code 401 Unauthorized indicates that your request lacks valid authentication credentials. So there must be a problem in your body that you are sending.
Try sending the body in this format:
body: 'grant_type=client_credentials&client_id=' + key + '&client_secret=' + secret,

Related

Nextjs - Requesting Spotify Access Token - unsupported_grant_type [duplicate]

I'm working on integrating spotify and I'm making my own api. I can't understand why my request is not working. It works fine in python but not when I use express.
I get this response body :
{"error":"unsupported_grant_type","error_description":"grant_type must be client_credentials, authorization_code or refresh_token"}
Express :
var http = require('http');
var express = require('express');
var bodyParser = require('body-parser');
var fetch = require('node-fetch');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }))
app.listen(80);
app.post('/v1/spotify/api/token', function(req, res) {
let body = req.body
let redirect_uri = body.redirect_uri
let code = body.code
let data = {
grant_type:'authorization_code',
redirect_uri:redirect_uri,
code:code
}
fetch('https://accounts.spotify.com/api/token', {
method: 'POST',
headers: {
'Authorization':'Basic *client_id:client_secret*',
'Content-Type':'application/x-www-form-urlencoded'
},
body: JSON.stringify(data)
}).then(r => r.json().then(data => res.send(data)))
});
Python:
r = requests.post("https://accounts.spotify.com/api/token",
data={
"grant_type":"authorization_code",
"redirect_uri":*redirect_uri*,
"code":*code*
},
headers = {
"Authorization": "Basic *client_id:client_secret*",
'Content-Type':'application/x-www-form-urlencoded'}
)
In your script of Node.js, data is sent as a string value. So how about this modification?
Modified script
Please modify the object of data as follows and try again.
// Below script was added.
const {URLSearchParams} = require('url');
const data = new URLSearchParams();
data.append("grant_type", "authorization_code");
data.append("redirect_uri", redirect_uri);
data.append("code", code);
fetch('https://accounts.spotify.com/api/token', {
method: 'POST',
headers: {
'Authorization':'Basic *client_id:client_secret*',
'Content-Type':'application/x-www-form-urlencoded'
},
body: data // Modified
}).then(r => r.json().then(data => res.send(data)))
Reference:
Post with form parameters of node-fetch
If this didn't work, I apologize.
I had to put the client_id and client_secret in the body and not in Authorization header.
try {
const body = {
grant_type: "client_credentials",
client_id: <YOUR_ID>,
client_secret: <YOUR_SECRET>,
};
const response = await fetch("https://accounts.spotify.com/api/token", {
method: "POST",
headers: {
"Content-type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams(body),
});
console.log({ response });
} catch (err) {
console.log({ err });
}

I'm trying to get a token from API login, but I get an Object null prototype

I am implementing API login with node js and javascript. I'm trying to get a token, but the console says Object: null prototype as shown below.
[Symbol(Response internals)]: {
url: 'https://URL(sensitive information)',
status: 200,
statusText: 'OK',
headers: Headers { [Symbol(map)]: [Object: null prototype] },
counter: 0
}
}
Below is my code.
export const startKakaoLogin = (req, res) => {
const baseUrl = "https://kauth.kakao.com/oauth/authorize?";
const config = {
client_id: process.env.KA_ID,
redirect_uri: process.env.KA_RE,
response_type: "code",
prompt: "login",
};
const params = new URLSearchParams(config).toString();
const finalUrl = `${baseUrl}&${params}`;
return res.redirect(finalUrl);
};
export const finishKakaoLogin = async (req, res) => {
const baseUrl = "https://kauth.kakao.com/oauth/token";
const config = {
grant_type: "authorization_code",
client_id: process.env.KA_ID,
redirect_uri: process.env.KA_RE,
code: req.query.code,
};
const params = new URLSearchParams(config).toString();
const finalUrl = `${baseUrl}&${params}`;
const tokenRequest = await fetch(finalUrl, {
method: "POST",
headers: {
Accept: "application/x-www-form-urlencoded;charset=utf-8",
},
body: finalUrl,
});
console.log(tokenRequest);
};
Additionally, In the reference, 'curl' was used, but I used 'fetch', did I do something wrong?
POST /oauth/token HTTP/1.1
Host: kauth.kakao.com
Content-type: application/x-www-form-urlencoded;charset=utf-8
curl -v -X POST "https://kauth.kakao.com/oauth/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "client_id=${REST_API_KEY}" \
--data-urlencode "redirect_uri=${REDIRECT_URI}" \
-d "code=${AUTHORIZE_CODE}"
What are you expecting to get from the endpoint? You're just logging the Response object right now and are seeing a representation of its internals.
To get e.g. the text from the response body, you'll need to parse it too, here with Response#text():
const text = await tokenRequest.text();
console.log(text);
If you're looking for JSON, then use Response#json().
const data = await tokenRequest.json();
console.log(data);
Be sure to check that the response's error code is what you expect, though, with e.g. tokenRequest.ok.

Using node-fetch effectively, getting invalid json response body error *only* the first time I query the server

I have been attempting to collect an API token from an undocumented API of a Ubiquiti EdgeMax Network switch and use it to check the status of the ports then eventually make some changes to the status of them when I receive the correct information.
I have put together some code using NodeJS and node-fetch that allows me to grab the API authentication token then use it to get some information on the interfaces.
It all seems to be working fine but I have noticed that the first time I run the NodeJS application and query it it would throw an
UnhandledPromiseRejectionWarning: FetchError: invalid json response body at... reason: Unexpected end of JSON input
This happens when I request the data to the switch with the API using the token. If I try the second time it works fine, even on multiple consecutive times.
I tried getting tweaking the async functions but the behavior is the same, is as if the token is not gathered quickly enough the first time the request is done. I am not as good with async JS code conventions so I wonder if is something wrong with my approach.
I just want to be able to make each of these request actions one after another effectively and return back the result to the server I'm making the query from. Any insights on this would be greatly appreciated.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const express = require("express");
const bodyParser = require("body-parser");
const fetch = require("node-fetch");
const app = express();
const PORT = process.env.PORT;
app.use(bodyParser.json());
const url = "https://example.com:9443/";
const credentials = { username: "ubnt", password: "ubnt" };
let status;
let token;
async function postData(url = '', path = '', body = {}) {
const response = await fetch(`${url}${path}`, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
Referer: url,
accept: "application/json, text/plain, */*",
"accept-language": "en-US,en;q=0.9,es;q=0.8",
"content-type": "application/json;charset=UTF-8",
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify(body)
}).then(response => response.json().then(json => ({
authToken: response.headers.get("x-auth-token"),
json
})))
return response;
}
async function getData(url = '', path = '', token = '') {
const response = await fetch(`${url}${path}`, {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
headers: {
Referer: url,
accept: "application/json, text/plain, */*",
"accept-language": "en-US,en;q=0.9,es;q=0.8",
"content-type": "application/json;charset=UTF-8",
"x-auth-token": token
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: null
}).then(response => response.json())
return response;
}
const statusHandler = (req, res) => {
const {
seed
} = req.body.input;
postData(url, 'api/v1.0/user/login', credentials)
.then(response => {
console.log(response.authToken);
token = response.authToken;
}).then(getData(url, 'api/v1.0/interfaces', token)
.then(response => {
console.log(response[0].status);
status = response[0].status;
}));
console.log(seed);
return res.json({
status,
});
};
app.post("/status", statusHandler);
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}...`);
});
Turns out I was using the functions incorrectly. I did not use an async function for the statusHandler. I was was not waiting for the reply from the api before proceeding with the next request. It seems that with the first requests the API responds a lot slower.
I fixed by waiting for a reply on each of the function declarations and their calls on the handler using async / await. Doing this allowed me to clean up the code a lot more making it more readable.
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const express = require("express");
const bodyParser = require("body-parser");
const fetch = require("node-fetch");
const app = express();
const PORT = process.env.PORT;
app.use(bodyParser.json());
const url = "https://example.com:9443/";
const credentials = { username: "ubnt", password: "ubnt" };
let status;
let token;
async function postData(url = '', path = '', body = {}) {
const response = await fetch(`${url}${path}`, {
method: 'POST',
mode: 'cors',
cache: 'no-cache',
credentials: 'same-origin',
headers: {
Referer: url,
accept: "application/json, text/plain, */*",
"accept-language": "en-US,en;q=0.9,es;q=0.8",
"content-type": "application/json;charset=UTF-8",
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: JSON.stringify(body)
})
const json = await response.json()
.then(json => ({
authToken: response.headers.get("x-auth-token"),
json
}));
return json
}
async function getData(url = '', path = '', token = '') {
const response = await fetch(`${url}${path}`, {
method: 'GET',
mode: 'cors',
cache: 'no-cache',
headers: {
Referer: url,
accept: "application/json, text/plain, */*",
"accept-language": "en-US,en;q=0.9,es;q=0.8",
"content-type": "application/json;charset=UTF-8",
"x-auth-token": token
},
redirect: 'follow',
referrerPolicy: 'no-referrer',
body: null
})
const json = await response.json()
return json
}
const statusHandler = async (req, res) => {
const {
seed
} = req.body.input;
await postData(url, 'api/v1.0/user/login', credentials)
.then(response => {
console.log(response.authToken);
token = response.authToken;
})
await getData(url, 'api/v1.0/interfaces', token)
.then(response => {
console.log(response[0].status);
status = response[0].status;
});
console.log(seed);
return res.json({
status,
});
};
app.post("/status", statusHandler);
app.listen(PORT, () => {
console.log(`Server listening on port ${PORT}...`);
});

missing authentification token for REST request elastic search

It's the first time I'm posting a question here: I'm creating a website in AngularJS for the front end and NodeJS for the back end. This website is supposed to give me information about my elastic search clusters, get some information from Elasticsearch index. I have tried to use Elasticsearch Javascript API to do my request but it doesn't work.
I'm using ElasticSearch 5.4
Here's an example of request :
var client = new elasticsearch.Client ({
host: 'https://noev02pe.fr:9200',
auth: 'user:password',
log: 'trace',
headers: {
'Authorization': 'Basic user:password',
}
});
export function connect() {
client.search({
index: 'metric-prod*',
q: 'kafka'
}
, function (error, response) {
console.log(response);
});
}
and the response on the console is :
{ error:
{ root_cause: [ [Object] ],
type: 'security_exception',
reason: 'missing authentication token for REST request [/metric-
prod*/_search?q=kafka]',
header: { 'WWW-Authenticate': 'Basic realm="security" charset="UTF-8"'
} },
status: 401 }
I also tried doing classic post request :
export function createUser(request,response,next){
var username = request.params.username;
var userData = querystring.stringify(request.body);
console.log(userData);
var options ={
hostname: 'noev02vr.fr',
port: 9200,
rejectUnauthorized: false,
path: "_xpack/security/user/"+username,
method:'POST',
headers: {
'Authorization': 'Basic ' + prodPass,
'Content-Type': 'application/json',
'Content-Length': userData.length
}
};
var post_req=http.request(options, function(res){
console.log('post user reussi');
res.on('data', function(data){
response.writeHead(res.statusCode);
response.write(data);
console.log(res.statusCode);
});
});
post_req.write(userData);
post_req.end();
}
and I get a 500 error.
Basic Authentication
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200', //Replace with your URL.
auth: {
username: 'elastic',
password: '*****' //Replace with your password
}
})
Otherwise, you can provide your credentials in the node(s) URL
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
node: 'https://username:password#localhost:9200'
})
If you have enable ssl then this are the config
const { Client } = require('#elastic/elasticsearch')
const client = new Client({
node: 'https://localhost:9200',
auth: {
username: 'elastic',
password: '*****'
},
ssl: {
ca: fs.readFileSync('./cacert.pem'),
rejectUnauthorized: false
}
})
You can get Your username and password refer this link
https://www.elastic.co/guide/en/cloud-enterprise/current/ece-password-reset-elastic.html

POST method through node.js

I am writing a simple node.js for a REST API call to create object through POST method and get the response code. But while running the script I get "0 passing" .
Here is my code:
var request = require("request");
var options = { method: 'POST',
url: 'https://example.org',
headers:
{ 'content-type': 'application/vnd.nativ.mio.v1+json',
authorization: 'Basic hashedTokenHere' },
//body: '{\n\n"name": "My JS TEST",\n"type": "media-asset"\n\n}'
};
request(options, function (error, response, body) {
if(error) {
console.log(error);
} else {
console.log(response.statusCode, body);
}
});
Can anyone help to to run it successfully and get the response code?
Thanks!
I calling my local API hope this will make thing get clear. It's work for me
This my API
var express = require('express')
var router = express.Router()
var bodyParser = require('body-parser');
var app=express()
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/api',function(req,res)
{
res.status(200).send(req.body.name+"hi");
})
app.listen(8080,function(){
console.log("start");
})
Now, through Request, i will request this post method
var request = require('request');
// Set the headers
var headers = {
'User-Agent': 'Super Agent/0.0.1',
'Content-type': 'application/json',
'Authorization': 'Basic ' + auth,
}
var postData = {
name: 'test',
value: 'test'
}
// Configure the request
var options = {
url: 'http://127.0.0.1:8080/api',
method: 'POST',
json: true,
headers: headers,
body: postData
}
// Start the request
request(options, function (error, response, body) {
// Print out the response body and head
console.log("body = "+body+" head= "+response.statusCode)
}
})

Categories