Axios post request results in 400 - Bad request - vue.js

I test an API with Postman and want to write a request with axios. This is what it looks like in Postman and it works fine.
This is my code in javascript:
axios.post('http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token', null,
{ params: {
grant_type : "password",
username: "test",
password: "password",
client_id: "admin-cli"
},
headers: {
'content-type': 'application/x-www-form-urlencoded'
},
}).then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
})
This results in the following error:
POST http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token?grant_type=password&username=test&password=password&client_id=admin-cli 400 (Bad Request)
I also tried to use curl, which also works:
curl -X POST http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token -H 'Content-Type: application/x-www-form-urlencoded' -d 'grant_type=password&username=test&password=password&client_id=admin-cli'
I guess there might be an error in my axios code, but I don´t know what might have gone wrong :-(

In your axios request you've send your data as parameters instead of form data.
Have a look at this thread to see how to send form data: axios post request to send form data

You gotta send in the second param exactly what you're sending into params;
So the new request would be something like this:
const data = {
grant_type: "password",
username: "test",
password: "password",
client_id: "admin-cli"
}
const url = 'http://127.0.0.1:8080/auth/realms/master/protocol/openid-connect/token'
axios.post(
url,
data, // data in the second param
{
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
}).then((response) => {
console.log(response)
}).catch((error) => {
console.log(error)
})

Related

Spotify returning 200 on token endpoint, but response data is encoded

I'm working through this tutorial on creating an app that uses the Spotify API. Everything was going great until I got to the callback portion of authenticating using the authentication code flow.
(I do have my callback URL registered in my Spotify app.)
As far as I can tell, my code matches the callback route that this tutorial and others use. Significantly, the http library is axios. Here's the callback method:
app.get("/callback", (req, res) => {
const code = req.query.code || null;
const usp = new URLSearchParams({
code: code,
redirect_uri: REDIRECT_URI,
grant_type: "authorization_code",
});
axios({
method: "post",
url: "https://accounts.spotify.com/api/token",
data: usp,
headers: {
"content-type": "application/x-www-form-urlencoded",
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64")}`,
},
})
.then(response => {
console.log(response.status); // logs 200
console.log(response.data); // logs encoded strings
if (response.status === 200) {
res.send(JSON.stringify(response.data))
} else {
res.send(response);
}
})
.catch((error) => {
res.send(error);
});
Though the response code is 200, here's a sample of what is getting returned in response.data: "\u001f�\b\u0000\u0000\u0000\u0000\u0000\u0000\u0003E�˒�0\u0000Ee�uS\u0015��\u000e�(\b\u0012h\u0005tC%\u0010\u0014T\u001e�����0��^޳:���p\u0014Ѻ\u000e��Is�7�:��\u0015l��ᑰ�g�����\u0"
It looks like it's encoded, but I don't know how (I tried base-64 unencoding) or why it isn't just coming back as regular JSON. This isn't just preventing me logging it to the console - I also can't access the fields I expect there to be in the response body, like access_token. Is there some argument I can pass to axios to say 'this should be json?'
Interestingly, if I use the npm 'request' package instead of axios, and pass the 'json: true' argument to it, I'm getting a valid token that I can print out and view as a regular old string. Below is code that works. But I'd really like to understand why my axios method doesn't.
app.get('/callback', function(req, res) {
// your application requests refresh and access tokens
// after checking the state parameter
const code = req.query.code || null;
const state = req.query.state || null;
const storedState = req.cookies ? req.cookies[stateKey] : null;
res.clearCookie(stateKey);
const authOptions = {
url: 'https://accounts.spotify.com/api/token',
form: {
code: code,
redirect_uri: REDIRECT_URI,
grant_type: 'authorization_code',
},
headers: {
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64')}`,
},
json: true,
};
request.post(authOptions, function (error, response, body) {
if (!error && response.statusCode === 200) {
const access_token = body.access_token;
const 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);
});
// we can also pass the token to the browser to make requests from there
res.redirect('/#' + querystring.stringify({
access_token: access_token,
refresh_token: refresh_token,
}));
} else {
res.redirect(`/#${querystring.stringify({ error: 'invalid_token' })}`);
}
});
});
You need to add Accept-Encoding with application/json in axios.post header.
The default of it is gzip
headers: {
"content-type": "application/x-www-form-urlencoded",
'Accept-Encoding': 'application/json'
Authorization: `Basic ${new Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString("base64")}`,
}

How to script for postman like API in cypress

I am new in Cypress,
I wanted to create my first code for API in cypress.
Here is the details
POST
https://www.mywebsite.com/myproject/get-customer-login-url
HEADER
------
KEY: token
VALUE: HKt7854UHTFGR78#78
DESCRIPTION:
KEY: Content-Type
VALUE: application/json
DESCRIPTION:
BODY
-----
RAW:
{
"customerid": "54607"
}
Using above parameters, I got below result and status in Postman.
RESULT:
"{\"url\":\"default.aspx?rootid=843&companyId=54607&eccuserid=0&isloginspecialrole=False&userid=e91zNO%2bBBCI%3d&t=view\",\"code\":\"1\"}"
STATUS"
200 OK
I need to made script for cypress using these POST URL and parameters/key.
And want response like
https://www.mywebsite.com/myproject/default.aspx?rootid=843&companyId=54607&eccuserid=0&isloginspecialrole=False&userid=e91zNO%2bBBCI%3d&t=view
can anyone help me out to my cypress script?.
Here's an example, you might have to adjust it. This example just validates that status of the response is 200 but you can validate response contents as well. Refer cypress docs for details:
describe('Test the api', function() {
it ('status should be 200', () => {
cy.request({
method: 'POST',
url: 'your-url',
followRedirect: false,
headers: {
'token': 'HKt7854UHTFGR78#78',
'Content-Type': 'application/json',
},
body: {"customerid": "54607"},
})
.then((response) => {
expect(response.status).to.equal(200)
})
})
})

post works with request module but not axios

Burned two hours of my life on this and wondering if fresh eyes can help.
I am attempting to contact auth0 to get access token for the management API.
The provide sample code, using request module, which works perfectly (I have replaced the key/secret values):
var request = require("request");
var options = { method: 'POST',
url: 'https://dev-wedegpdh.auth0.com/oauth/token',
headers: { 'content-type': 'application/json' },
body: '{"client_id":"myID","client_secret":"mySecret","audience":"https://dev-wedegpdh.auth0.com/api/v2/","grant_type":"client_credentials"}' };
request(options, function (error, response, body) {
if (error) throw new Error(error);
res.json(JSON.parse(response.body).access_token)
});
I have my ID and Secret stored in .env file, so was able to adjust to this, which also works fine:
var options = { method: 'POST',
url: 'https://dev-wedegpdh.auth0.com/oauth/token',
headers: { 'content-type': 'application/json' },
body:
JSON.stringify({
grant_type: 'client_credentials',
client_id: process.env.auth0AppKey,
client_secret: process.env.auth0AppSecret,
audience: 'https://dev-wedegpdh.auth0.com/api/v2/'})
}
request(options, function (error, response, body) {
if (error) throw new Error(error)
res.json(JSON.parse(response.body).access_token)
})
I try to make the exact same request using axios and I receive 404 error:
let response = await axios.post(
'https://dev-wedegpdh.auth0.com/api/v2/oauth/token',
JSON.stringify({
grant_type: 'client_credentials',
client_id: process.env.auth0AppKey,
client_secret: process.env.auth0AppSecret,
audience: 'https://dev-wedegpdh.auth0.com/api/v2/'
}),
{
headers: {'content-type': 'application/json'},
}
)
I have tried several different formats or configurations for the post function including those found
here and here etc.
Anyone see what I am doing wrong???
In axios post body, you need to send data as JSON, no need to use JSON.stringify.
let response = await axios.post(
"https://dev-wedegpdh.auth0.com/api/v2/oauth/token",
{
grant_type: "client_credentials",
client_id: process.env.auth0AppKey,
client_secret: process.env.auth0AppSecret,
audience: "https://dev-wedegpdh.auth0.com/api/v2/"
},
{
headers: { "content-type": "application/json" }
}
);

How to send data to server and fetched response using react native application?

I am trying to learn react native application by making a simple login page using api call. Where I will send user name and password to api and it will give me response. But I can't do it. Well I am sharing my code here.....
var myRequest = new Request('<my API >', {method: 'POST', body: '{"username":this.state.uName , "password":this.state.pwd}'});
fetch(myRequest).then(function(response) {
alert('Res'+response);
}).then(function(response) {
alert('Blank'+response);
})
.catch(function(error) {
alert('Error'+error);
});
I think the way of passing my user name and password to server is wrong. Please give me some idea then I can understand what is wrong here.
var data = {
"username": this.state.username,
"password": this.state.password
}
fetch("https://....", {
method: "POST",
headers: headers,
body: JSON.stringify(data)
})
.then(function(response){
return response.json();
})
.then(function(data){
console.log(data)
});
I hope this helps.
You need to Stringify the json data to send request as Post method with Json parameters as you are trying to do...
Here is the example code for how to encode data before requesting for response
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
Here is the sample code for login :
fetch(<hostURL>, {
method: 'POST',
headers: { 'Accept': 'application/json','Content-Type': 'application/json',},
body: JSON.stringify({ userName: <userName> ,Password: <Password>,})
}).then((response) => response.json())
.then((responseData) => {
console.log(responseData);
}).catch((error) => {
console.log("Error");
});
As the commentators before me stated, you simply need to stringify your JSON Body. In general, I' suggest that you incorporate e.g. api sauce into you stack. It is a comprehensive wrapper around the axios library, providing standardized errors and an ok key for quick checks.

How do i get the status of my response when using fetch in react-native?

I am making Log In page for my react native application. My api sends different response when my username and password are valid and invalid. So I want to track and save the status of my response in some state variable and then later perform function accordingly. Please suggest me way to do that.
doSignUp() {
console.log("inside post api");
fetch('MyApiUrl', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
password: this.state.password,
email:this.state.email,
name: this.state.firstname,
last_name :this.state.last_name,
mobile:this.state.mobile,
ssn:"2222222"
})
}).then((response) => {console.log('response:',response.status);
response.json()}
.then((responseData) => {
console.log("inside responsejson");
console.log('response object:',responseData)
console.log('refresh token:',responseData[0].token.refresh_token)
console.log('access token:',responseData[0].token.access_token);
}).done();
}
As far as I understand you want to know the http status code of your fetch request.
Usually your response object includes a "status" property. So you should be able to receive the status code by using this:
response.status
In case of a successful request this will return 200.