simple api with basic auth - node.js

I have:
const https = require('https');
const axios = require('axios');
exports.getEvents = async (req, res) => {
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
try {
await axios.get('http://localhost/api/events',
{
httpsAgent,
auth: {
username: "senstar",
password: "senstar"
}
}).then(resp => {
res.json(resp.data);
});
} catch (error) {
console.error(error);
}
}
this's a simple api, I test http://localhost/api/events' on postman, using Authorization: Basic Auth and work it. So I implement the function getEvents to get the results on node js, but this's not working, why? what's wrong? with basic auth?

Try this code
const https = require('https');
const axios = require('axios');
const base64 = require('base-64');
exports.getEvents = async (req, res) => {
try {
await axios.get('https://127.0.0.1/api/events',
{
headers: {
'Authorization': 'Basic ' + base64.encode("senstar" + ":" + "senstar")
}
}).then(resp => {
res.json(resp.data);
});
} catch (error) {
console.error(error);
}
}

Related

Expressjs API variables undefined

i'm trying to create my first API using nodejs / express js for backend and React for frontend. I'm able to call the API via postman but not via localhost on frontend as the path returns "undefined" and my "mediaType" and "id" are undefined.
The frontend should call the API
BACKEND
const express = require("express");
const app = express();
const PORT = 8080;
const axios = require("axios");
app.use(express.json());
app.get("/test", (req, res) => {
// const { mediaType, id } = req.params;
const { mediaType, id } = req.body;
const options = {
methond: "GET",
url: `https://api.themoviedb.org/3/${mediaType}/${id}?api_key=${APIKEY}&language=en-US`,
// headers: {
// }
};
axios.request(options).then((response) => {
res.send(response.data);
}).catch((error) => {
console.log(error)
})
});
FRONTEND
const fetchData = async () => {
const { data } = await axios.get(
`http://localhost:8080/test`, { params: { mediaType: mediaType, id: id } }
);
setContent(data);
};
PART OF HEADER
_header: 'GET /3/undefined/undefined?api_key=XXX&language=en-US HTTP/1.1\r\n' +
'Accept: application/json, text/plain, */*\r\n' +
'User-Agent: axios/0.27.2\r\n' +
'Host: api.themoviedb.org\r\n' +
'Connection: close\r\n' +
'\r\n',
Alright, for anyone interested...
i updated the FE req
const fetchData = async () => {
const { data } = await axios.get(
`http://localhost:8080/test2?mediaType=${mediaType}&id=${id}`
);
setContent(data);
};
And changed the BE req also, to use query parameters
app.get("/test2", (req, res) => {
// const { mediaType, id } = req.params;
mediaType = req.query.mediaType;
id = req.query.id;
const options = {
methond: "GET",
url: `https://api.themoviedb.org/3/${mediaType}/${id}?api_key=${apiKey}&language=en-US`,
// headers: {
//
}
};
axios
.request(options)
.then((response) => {
res.send(response.data);
})
.catch((error) => {
console.log(error);
});
});
Also needed to update CORS (no idea how it works????) as it blocked my localhost testing
const cors = require("cors");
app.use(
cors({
origin: "http://localhost:3000",
credentials: true, //access-control-allow-credentials:true
optionSuccessStatus: 200,
})
);
Now it seems that everything works!
You accept body parameters in your API endpoint
so with axios you should use data parameter with your body data included and send it to your backend:
const fetchData = async () => {
const { data } = await axios.get(
`http://localhost:8080/test`, { data: { mediaType: mediaType, id: id } } <--- check data key here
);
setContent(data);
};
by the way, it's not a good idea to send body HTTP request with GET http verb

Cannot save email in React.js + Express

So I have a function getProfile(). Inside it I am trying to fetch users from the server using a POST call, however it's throwing a CORS error in its response.
Here is the getProfile:
const getProfile = async () => {
try {
const res = await fetch("http://localhost:5000/dashboard/", {
method: "POST",
headers: {
jwt_token: localStorage.token,
"Content-Type": "application/json",
Accept: "application/json",
},
});
const parseData = await res.json();
setEmail(parseData.email);
console.log("Try success");
console.log(parseData.email);
} catch (err) {
console.log("Try failed");
console.error(err.message);
}
};
if you are handling your nodeServer by your own you need to add CORS package
please check this and follow their docs
https://www.npmjs.com/package/cors
1.install package
2. in your app.js file add following
var cors = require('cors')
app.use(cors())
and change you frontend function getProfile() to following:
const getProfile = async () => {
let token = localStorage.getItem("token");
const myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", "bearer" + token);
try {
await fetch("http://localhost:5000/dashboard/", {
method: "POST",
headers: myHeaders,
})
.then((r) => r.json().then((data) => ({ status: r.status, data })))
.then((obj) => obj.status === 200 && console.log("data", obj.data));
} catch (err) {
console.error("Try failed", err.message);
}
};

Extracting values from API data in node.js

Thank you for your time.
I'm trying to use OAuth2 in discord, but I'm having a hard time figuring out how to retrieve the username.
Can someone please tell me how to do it?
code
const fetch = require('node-fetch');
const express = require('express');
const app = express();
app.get('/', async ({ query }, response) => {
const { code } = query;
if (code) {
try {
const oauthResult = await fetch('https://discord.com/api/oauth2/token', {
method: 'POST',
body: new URLSearchParams({
client_id: process.env['ci'],
client_secret: process.env['cs'],
code,
grant_type: 'authorization_code',
redirect_uri: `https://oauth.aiueominato1111.repl.co`,
scope: 'identify',
}),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
});
const oauthData = await oauthResult.json();
const userResult = await fetch('https://discord.com/api/users/#me', {
headers: {
authorization: `${oauthData.token_type} ${oauthData.access_token}`,
},
});
console.log( await userResult.json());
} catch (error) {
// NOTE: An unauthorized token will not throw an error;
// it will return a 401 Unauthorized response in the try block above
console.error(error);
}
}
return response.sendFile('index.html', { root: '.' });
});
app.listen(port, () => console.log(`App listening at http://localhost:${port}`));
thank you
You already have the JSON data (from await userResult.json()) with it you can either get the property from the object or destructure it.
Getting property
const user = await userResult.json();
const username = user.username
Destructuring
const { username, id } = await userResult.json()
You can find out more about what properties you can extract from the Discord documentation

Axios and Oauth1.0 - 'status: 400, Bad Request'

I'm new on Nodejs and all the modules related with Node. I've been trying to use axios for send a Oauth1.0 Autorization signature, but i'm getting: response: { status: 400, statusText: 'Bad Request', ...}
import { BASE_URL } from '../../../config/config.js';
import axios from 'axios';
import status from 'http-status';
import OAuth from 'oauth-1.0a';
import { createHmac } from 'crypto';
import dotenv from 'dotenv';
dotenv.config();
const CONSUMERKEY = process.env.consumer_key;
const CONSUMERSECRET = process.env.consumer_secret;
const TOKENKEY = process.env.access_token;
const TOKENSECRET = process.env.token_secret;
export const oauth = OAuth({
consumer: {
key: CONSUMERKEY,
secret: CONSUMERSECRET,
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return createHmac('sha1', key)
.update(base_string)
.digest('base64')
},
})
export const token = {
key: TOKENKEY,
secret: TOKENSECRET,
}
const doRequest = async (query) => {
const request_data = {
url: `${BASE_URL}`,
method: 'GET',
params: { q: `${query}` },
};
const authHeader = oauth.toHeader(oauth.authorize(request_data, token));
return await axios.get(request_data.url, request_data.params, { headers: authHeader });
};
const searchU = async (term) => {
return await doRequest(`${term}`);
};
export const userS = async (req, res, next) => {
try {
const { query } = req;
const { data } = await searchU(query.q);
const string = JSON.stringify(data);
const Rs = JSON.parse(string);
const response = {
code: 1,
message: 'sucess',
response: Rs
};
res.status(status.OK).send(response);
} catch (error) {
next(error);
if (error.response){
console.log("Response: ");
console.log(error.response);
} else if(error.request){
console.log("Request: ");
console.log(error.request)
} else if(error.message){
console.log("Message: ");
console.log(error.message)
}
}
};
I've been also trying the solution given On this post: but there's no way I can make this work, no idea what i could be doing wron...
When i try the following code (see below), using Request module (which is deprecated) works well, but I really need to do it with Axios...
const request_data = {
url: `${BASE_URL}`,
method: 'GET',
params: { q: `${query}` },
};
const authHeader = oauth.toHeader(oauth.authorize(request_data, token));
request(
{
url: request_data.url,
method: request_data.method,
form: request_data.params,
headers: authHeader,
},
function(error, response, body) {
console.log(JSON.parse(body));
}
)
Any thoughts on what I'm doing wrong on this?? Thank you very much!!
Refer to the following link for the Request Config for Axios. I believe you need to have the query params after the header in the axios.get()
Axios Request Config
Try, the following and see how it goes:-
return await axios.get(request_data.url, { headers: authHeader }, request_data.params);

How can I get Axios to send a request with FormData?

I'm unable to get the server that I'm calling to recognize the FormData that I'm providing when I use axios. It keeps telling me that I'm not providing the right FormData even though it works in Postman and Node native http (see below):
import { Router } from "express";
import axios from "axios";
import * as FormData from "form-data";
const router = Router();
const cookieHeader = {
Cookie: "XXX",
};
router.get("/", async (_req, res) => {
try {
const formData = new FormData();
formData.append("key1", JSON.stringify(["value1"]));
formData.append("key2", "value2");
formData.append("key3", "value3");
const response = await axios.post("https://xxx", formData, { headers: { "Content-Type": "multipart/form-data; boundary=--------------------------811161660471543283806813" } });
res.send(response.data);
} catch (error) {
console.log(error);
}
});
module.exports = router;
I am able to get it working in Postman and used that to export using Node's native http, which also works:
import { Router } from "express";
import { https } from "follow-redirects";
const router = Router();
router.get("/", () => {
const options = {
method: "POST",
hostname: "xxx",
path: "/xx/xxx",
headers: {
"Content-Type": "multipart/form-data; boundary=--------------------------811161660471543283806813",
Cookie: "xxx",
},
maxRedirects: 20,
};
const req = https.request(options, (res: any) => {
const chunks: any[] = [];
res.on("data", (chunk: any) => {
chunks.push(chunk);
});
res.on("end", () => {
const body = Buffer.concat(chunks);
console.log(body.toString());
});
res.on("error", (error: any) => {
console.error(error);
});
});
const postData = `------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key1\"\n\n[\"value1\"]\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key2\"\n\nvalue2\n------WebKitFormBoundary7MA4YWxkTrZu0gW\nContent-Disposition: form-data; name=\"key3\"\n\nvalue3\n------WebKitFormBoundary7MA4YWxkTrZu0gW--`;
req.setHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");
req.write(postData);
req.end();
});
module.exports = router;
I figured it out after reading through https://github.com/axios/axios/issues/318. It wasn't until near the end that Googrosh posted that he used .getHeaders(). Lo and behold, I added that to my headers too and it worked.
So updating my code, here's what it looks like:
const response = await axios.post("https://xxx", formData, { headers: formData.getHeaders() });
onst formUrlEncoded = x =>
Object.keys(x).reduce((p, c) => p + `&${c}=${encodeURIComponent(x[c])}`, '')
var axios = require("axios");
axios({
url: 'https://login.xyz.com/oauth/v2/token',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: formUrlEncoded({
client_id: '***',
client_secret: '***',
grant_type: 'authorization_code',
})
})
.then(function(response) {
console.log(response.data)
})
.catch(function(error) {
console.log(error)
})

Resources