BAD_REQUEST_ERROR - Nodejs Request Method - javascript

I am working on payment gateway integration and had to call the orders api. But i keep getting the error
{"error":{"code":"BAD_REQUEST_ERROR","description":"Please provide your api key for authentication purposes."}}
My whole section of code
const functions = require('firebase-functions');
var express = require('express');
var cors = require('cors');
var request = require('request');
const crypto = require('crypto');
var app = express();
app.use(cors({origin:true}));
app.post("/",(req,res)=>{
const amount = req.body.amount;
const key = '----insert your key here----';
const key_secret = '----- insert key secret here ----';
var options = { method: 'POST',
url: 'https://api.razorpay.com/v1/orders',
headers:
{
Authorization: 'Basic' + new Buffer(key + ":" + key_secret).toString("base64")},
form:
{ amount: amount,
currency: 'INR',
receipt: "Receipt #20",
payment_capture : 1
}
};
request(options, (error, response, body)=> {
if (error) throw new Error(error);
res.send(body);
});
})
exports.razorpaymentApi = functions.region('asia-east2').https.onRequest(app);
I have replaced key and key_secret with my original api key and secret. Can you tell me where i am going wrong. Thanks

I modified header as
headers:
{
"authorization" : "Basic xxxxMyEncodedString"
},
This worked for me.

try this
"authorization" = (new Buffer(key + ":" + key_secret, 'base64')).toString('utf8');
i refered this
https://www.dotnetcurry.com/nodejs/1231/basic-authentication-using-nodejs

Related

{"error":"invalid_client"} client credentials error spotify with express

I am developping an api on spotify.
I want to retrieve clients credentials. I set up my app on the dashboard.
My client_id and secret are correct.
But I have the same error at the end when I try to retrieve this client credential: "error":"invalid_client"
I look for my problem on web but no one correspond to my problem.
Here is my code:
`
const express = require("express");
const path = require("path");
const cors = require("cors");
const fetch = (...args) =>
import('node-fetch').then(({default: fetch}) => fetch(...args));
const request = "https://accounts.spotify.com/api/token";
const code = Buffer.from(client_id + ":" + client_secret).toString("base64");
const app = express();
const optionsTOKEN = {
method: "POST",
body: "grant_type=client_credentials",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Basic" +code
},
// json: true,
};
app.get("/code", async (req, res) => {
const data = await retrieveCode(request, optionsTOKEN);
console.log(res.statusCode)
res.send(data);
});
app.listen(8888, () => {
console.log("server running on port 8888");
});
async function retrieveCode(URlRequest, options) {
try {
const res = await fetch(URlRequest, options);
console.log(res);
const data = await res.json();
console.log("la data vaut" + data);
return data
} catch (err) {
console.log(`L'erreur: ${err}`);
}
}
`
Thank you for your help
I try to modify the parameters in my options, set up a new project on my dahsboard, change my port.
I am expecting to retrieve the access token
You needs to add a space between "Basic" and code
before
"Basic" +code
After
"Basic " +code
#1 With this code
This full test code with hide client_id and client_secret
const express = require("express");
const fetch = (...args) =>
import('node-fetch').then(({ default: fetch }) => fetch(...args));
const request = "https://accounts.spotify.com/api/token";
const client_id = "32-your-client-id-7b";
const client_secret = "ab-your-client_secret-9e";
const code = Buffer.from(client_id + ":" + client_secret).toString("base64");
const app = express();
const optionsTOKEN = {
method: "POST",
body: "grant_type=client_credentials",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": "Basic " + code
},
// json: true,
};
app.get("/code", async (req, res) => {
const data = await retrieveCode(request, optionsTOKEN);
console.log(res.statusCode)
res.send(data);
});
app.listen(8888, () => {
console.log("server running on port 8888");
});
async function retrieveCode(URlRequest, options) {
try {
const res = await fetch(URlRequest, options);
console.log(res);
const data = await res.json();
console.log("la data vaut" + JSON.stringify(data));
return data
} catch (err) {
console.log(`L'erreur: ${err}`);
}
}
#2 Using this dependencies
package.json for npm install
{
"dependencies": {
"express": "^4.18.2",
"node-fetch": "^3.3.0"
}
}
#3 npm install
#4 npm start
#5 access from browser http://localhost:8888/code
Response in console
la data vaut{"access_token":"BQCuVhXlpVQGKGxqK-remove-some-string-nX6sQp8uPSYBMh5lsU","token_type":"Bearer","expires_in":3600}
200
In Browser,

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 });
}

How can I write a txt file in React?

I have a issue. I'm doing a project with React. My project is simply for listening to music on Spotify. It is necessary to train the code of the room entered from the home page to the url extension that I will use for Spotify. The api link I use for Spotify uses node.js, so it allows file reading, but I want it to write the code of the room I clicked in React at that time into that txt file. How can I do that?
My only wish is to save the room.id variable in the homepage file into the txt file in another way.
Example of homepage.js
<Heading as="h1" mb={6}>
Rooms
</Heading>
<Divider orientation="horizontal" />
{rooms.map((room)=> (
<ListItem>
<ListItemText primary={room.roomName} secondary={room.roomInfo}/>
{/* <Link to={`/room/${room.id}`}></Link> */}
<Link to={`/room/${room.id}`}>
<Button>
Join Room
</Button>
</Link>
</ListItem>))}
Example of Spotify redirect code..
/**
* This is an example of a basic node.js script that performs
* the Authorization Code oAuth2 flow to authenticate against
* the Spotify Accounts.
*
* For more information, read
* https://developer.spotify.com/web-api/authorization-guide/#authorization_code_flow
*/
var express = require('express'); // Express web server framework
var request = require('request'); // "Request" library
var cors = require('cors');
var querystring = require('querystring');
var cookieParser = require('cookie-parser');
/**
* Generates a random string containing numbers and letters
* #param {number} length The length of the string
* #return {string} The generated string
*/
var generateRandomString = function(length) {
var text = '';
var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
for (var i = 0; i < length; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
};
var stateKey = 'spotify_auth_state';
var app = express();
app.use(express.static(__dirname + '/public'))
.use(cors())
.use(cookieParser());
app.get('/login', function(req, res) {
var state = generateRandomString(16);
res.cookie(stateKey, state);
// your application requests authorization
var scope = 'user-read-private user-read-email user-read-playback-state user-modify-playback-state user-read-currently-playing';
res.redirect('https://accounts.spotify.com/authorize?' +
querystring.stringify({
response_type: 'code',
client_id: client_id,
scope: scope,
redirect_uri: redirect_uri,
state: state
}));
});
app.get('/callback', function(req, res) {
// your application requests refresh and access tokens
// after checking the state parameter
var code = req.query.code || null;
var state = req.query.state || null;
var storedState = req.cookies ? req.cookies[stateKey] : null;
if (state === null || state !== storedState) {
res.redirect('/#' +
querystring.stringify({
error: 'state_mismatch'
}));
} else {
res.clearCookie(stateKey);
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: redirect_uri,
grant_type: 'authorization_code'
},
headers: {
'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token,
refresh_token = body.refresh_token;
var options = {
url: 'https://api.spotify.com/v1/me',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
// use the access token to access the Spotify Web API
request.get(options, function(error, response, body) {
console.log(body);
});
var fs = require('fs');
var roomCodeTxt = fs.readFileSync('roomCodeText.txt', 'utf-8');
// we can also pass the token to the browser to make requests from there
res.redirect(`http://localhost:3000/room/${roomCodeTxt}\#` +
querystring.stringify({
access_token: access_token,
refresh_token: refresh_token
}));
} else {
res.redirect('/#' +
querystring.stringify({
error: 'invalid_token'
}));
}
});
}
});
app.get('/refresh_token', function(req, res) {
// requesting access token from refresh token
var refresh_token = req.query.refresh_token;
var authOptions = {
url: 'https://accounts.spotify.com/api/token',
headers: { 'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64')) },
form: {
grant_type: 'refresh_token',
refresh_token: refresh_token
},
json: true
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var access_token = body.access_token;
res.send({
'access_token': access_token
});
}
});
});
console.log('Listening on 8888');
app.listen(8888);
You can write to a file in node also. See fs.writeFileSync (because this is a server, fs.writeFile or fs.promises.writeFile would help with performance, but for something this little, it shouldn't really matter).
The basic idea is in node, when the user clicks your button, you'll send a request to your server to write a file. Something roughly like this:
// Using the native fetch API
const joinRoom = roomId => {
return fetch('/write/to/file/endpoint', {
body: JSON.stringify({ roomId: roomId }),
// This header lets the server know that what you're sending is JSON
headers: { 'Content-Type': 'application/json' },
method: 'POST'
})
}
// With axios (Added this example in reponse to the O.P.'s comment)
const joinRoom = roomId => {
// Axios will add the Content-Type: application/json header by default
return axios.post('/write/to/file/endpoint', { roomId: roomId })
}
...
<button onClick={() => joinRoom(room.id)}>Join Room</button
In your server, you just need to handle requests to this new endpoint and call fs.writeFileSync('roomCodeText.txt', roomId, 'utf-8'). The specific details for how this works depends on how you're handling requests (in vanilla node? With the express library?) You can refer to this stackoverflow question on how to retrieve a POST body in node. There's answers for both express and node. The specific answer I linked to explains how to do it with vanilla node. It assumed that url-encoded data was send in the POST body. We're sending JSON in the above example, so you just need to take that code snippet and replace qs.parse(body) with JSON.parse(body).

Parse response body from request and return back to client

I am new to node.js and JavaScript in general, but I'm trying to use node.js as a simple REST API. A client request comes to node.js, then node.js reaches out to a database to perform crud operations and returns the response back. However, I would like to be able to parse this response and format it in my own JSON before sending back to the client. Right now im using the request library and .pipe() to send back. Can I .pipe() into a variable that I could then parse or do I need to change my approach entirely?
Here is what my code looks like at the current moment:
const request = require('request');
var username = "admin";
var password = "admin";
var auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
exports.getPosts = (req, res, next) => {
request({
uri: 'http://localhost:8000/LATEST/search?q=caesar',
headers: {"Accept": "application/json",
"Authorization": auth
}
}).pipe(res);
};
I am aware that request has been deprecated so maybe there is a better way to do this currently. I appreciate any help and feedback as I'm new to this.
You can use request module or axios or anything. You can just save the JSON body and process it and sent it to the client. Below is how to do it.
const request = require('request');
var username = "admin";
var password = "admin";
var auth = "Basic " + new Buffer(username + ":" + password).toString("base64");
exports.getPosts = (req, res, next) => {
request({
uri: 'http://localhost:8000/LATEST/search?q=caesar',
headers: {
"Accept": "application/json",
"Authorization": auth
}
// You can set json:true here so that you don't have to do JSON.parse below.
}, (err, response, body)=>{
//body is the json body
const jsonBody = JSON.parse(body);
//do something with json request
res.json(jsonBody);
})
};

Unexpected token - while parsing json request

I have two node servers and I am trying to send files between them using a rest api. However when I am sending the data I get a "Unexpected token -"on the receiving server. On the sender I get an [Error: write after end].
My router code:
var express = require('express');
var multer = require('multer');
var path = require('path');
var Router = express.Router;
const MODULES_PACKAGES_UPLOAD_DIR = path.resolve('/tmp');
module.exports = function() {
var router = new Router();
var storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, MODULES_PACKAGES_UPLOAD_DIR);
}
});
var upload = multer({storage: storage});
router.post('/fileUpload', upload.array(), function(req, res){
debug('We have a a file');
//Send the ok response
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('\n');
}
The sending code:
var Util = require('util');
var http = require('request-promise');
var request = require('request');
var fs = require('fs');
var Post = require('http');
var FormData = require('form-data');
//Generate the form data
var formdata = modules.map(function(fileName){
return fs.createReadStream('/opt/files/'+fileName);
});
var data = getData(); //Gets the body of the code as a promise
return Promise.all(data)
.then(function(dataResults){
var options = {
method: 'POST',
uri: 'https://' + name +'/file',
rejectUnauthorized: false,
timeout: 2000,
body: {
keys: keyResults,
modules: modules,
},
formData: { <====== If I remove this section everything works
'module-package': formdata,
},
json: true // Automatically stringifies the body to JSON
};
request.post(options, function(err, response){
if( err){
debug('Error: ',err);
}
else{
debug('We posted');
}
});
The weird thing is that if I remove the formData section then everything works but when it is there I get an exception that says:
SyntaxError: Unexpected token -
at parse (/home/.../projects/node_modules/body-parser/lib/types/json.js:83:15)
Does anyone have any idea what I could be doing wrong??
Just in case anyone in the future comes with the same problem. As #Bergi mentioned. You cant have both json data and form data. You need to choose either one. The solution is to just pass the json data as apart of the form like.
var options = {
method: 'POST',
uri: 'https://' + name +'/file',
rejectUnauthorized: false,
timeout: 2000,
body: {
},
formData: {
'module-package': formdata,
keys: keyResults,
modules: modules,
},
json: true // Automatically stringifies the body to JSON
};
request.post(options, function(err, response){
if( err){
debug('Error: ',err);
}
else{
debug('We posted');
}
});
In my case, the header of the HTTP Request contained "Content-Type" as "application/json".
So here are the things to check:
Send only either form-data or json body. NOT BOTH.
Check for Headers if the "Content-Type" is mentioned. Remove that.

Categories