I have a code in zapier:
var username = "username"
var password = "password"
var grant_type = "password"
var client_id = "id"
var ENDPOINT="someUrl"
var json = {
"grant_type": grant_type,
"username": username,
"password": password,
"client_id": client_id
};
var options={
method:"POST",
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
payload:json
}
const result = await fetch(WAVITY_ENDPOINT,options)
const content = await result.json()
output={response:content}
But I am always getting Unauthorized error. I do the same through request module and it works. I think fetch is not sending the data. Any help would be appreciated.In my request module code, I have following options:
headers: {
connection: "Keep-Alive",
timeout: 5000
},
url: ENDPOINT,
method: 'POST',
formData: {
'grant_type': grant_type,
'username': username,
'password': password,
'client_id': client_id
}
NOTE: Changing the headers of fetch to headers like in request also does not work for me.
Per this question about fetch, I believe the key for the data should be body, not payload.
Zapier uses node-fetch (source), so if you can get it working locally with that, you'll be able to paste it into Zapier successfully.
Related
I'm getting this odd error in nodejs when I try to send a post request with oauth-1.0a and node.js.
Request:
Headers:
Authorization: OAuth <...>
Accept: 'application/xml',
Content-Type: 'application/xml'
Body:
<account>
<firstName>${first}</firstName>
<lastName>${last}</lastName>
<email>${email}</email>
<urlRedirect>${redirecturl}</urlRedirect>
</account>`
Response:
401
An error occurred while trying to authenticate: Failed to validate signature.
Code:
require('dotenv').config()
const request = require('request')
const OAuth = require('oauth-1.0a')
const crypto = require('crypto')
var first = "real";
var last = "person";
var email = "real#person.com";
var redirecturl = "http://google.com"
const oauth = OAuth({
version: '1.0a',
consumer: {
key: process.env.CONSUMERKEY,
secret: process.env.CONSUMERSECRET,
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return crypto
.createHmac('sha1', key)
.update(base_string)
.digest('base64')
},
})
console.log(oauth)
const token = {
key: process.env.KEY,
secret: process.env.SECRET,
}
const request_data = {
url: `https://${process.env.CHURCHCODE}.fellowshiponeapi.com/v1/Accounts`,
method: 'POST',
data: `<account>
<firstName>${first}</firstName>
<lastName>${last}</lastName>
<email>${email}</email>
<urlRedirect>${redirecturl}</urlRedirect>
</account>`
}
const headers = Object.assign( oauth.toHeader(oauth.authorize(request_data, token)), {
Accept: 'application/xml',
'Content-Type': 'application/xml'
});
console.log(headers);
request(
{
url: request_data.url,
method: request_data.method,
headers: headers
},
function(error, response, body) {
console.log(response.statusCode)
console.log(response.statusMessage)
}
)
Why is this error occurring?
Edit: one of the more useful resources I used was this: https://oauth.net/core/1.0/#signing_process but I still can't figure this out.
Should also mention that this request does work, as in postman it successfully goes through.
You typically want to provide the token in a request using this header:
Authorization: Bearer <token>
Not
Authorization: OAuth <...>
I get this error, when I want to get a new refresh token from autodesk.
https://forge.autodesk.com/en/docs/oauth/v2/reference/http/refreshtoken-POST/
developerMessage: 'content-type header missing or unsupported content-type used, must use application/x-www-form-urlencoded'
bim360Router.use(async (req, res, next) => {
//verify if forge token is set in the cookies and not expired
let accessToken = req.cookies['access_token'];
let refresh_token = req.cookies['refresh_token'];
if(refresh_token && !accessToken) { //if token is expired, then generate a new token if refresh token is set
const config ={
headers : {
'content-type': 'application/x-www-form-urlencoded',
},
params : {
client_id: process.env.FORGE_CLIENT_ID,
client_secret: process.env.FORGE_CLIENT_SECRET,
refresh_token: refresh_token,
grant_type: 'refresh_token',
}
};
const response = await axios.post(
'https://developer.api.autodesk.com/authentication/v1/authenticate',
config
);
accessToken = await response.data.access_token;
//set access token as a cookie for session
res.cookie('access-token', accessToken, { maxAge: 60 * 60 * 1000, httpOnly: true });
console.log("middleware", response.data);
}
next();
});
I also try with headers : {
'Content-Type': 'application/x-www-form-urlencoded',
}, but I still get the same error.
(But when I try with curl it's working).
What I'm missing ?
I solved this problem by doing this. I have absolutely no idea why it works but if anyone can answer. I find this code confusing.
const response = await axios.post(
'https://developer.api.autodesk.com/authentication/v1/refreshtoken',
new URLSearchParams({
'client_id': process.env.FORGE_CLIENT_ID,
'client_secret': process.env.FORGE_CLIENT_SECRET,
'grant_type': 'refresh_token',
'refresh_token': refresh_token,
})
);
try sending payload url-encoded
const params = new URLSearchParams();
params.append('client_id', process.env.FORGE_CLIENT_ID);
// ... other params
axios.post(..., params);
From autodesk docs:
Request
Body Structure
The request body is a URL-encoded string of ampersand-concatenated, name-value pairs of the following parameters:
I have formatted an axios post request as follows:
var config = {
method: 'post',
url: 'https://us.battle.net/oauth/token',
headers: {
'Authorization': 'Basic '+process.env.BATTLENET_CLIENT+':'+process.env.BATTLENET_SECRET,
...data.getHeaders()
},
data : data
};
This is getting rejected with a 401. However, when I generate the code snippet for this out of Postman, which functions, it is the same, except the Authorization is a seemingly random string that was generated:
var config = {
method: 'post',
url: 'https://us.battle.net/oauth/token',
headers: {
'Authorization': 'Basic reallyRandomLongStringIsNotClientIDAndSecretKey=',
...data.getHeaders()
},
data : data
};
Plugging this into my code made it work. I'm curious if there is something I'm missing when coding Basic Auth credentials, as it seems Postman has converted/encrypted it into something I can not figure out?
You just need to encode the string with username and password/secret to Base64 like this:
const encodedAuthorization = Buffer.from(`${process.env.BATTLENET_CLIENT}:${process.env.BATTLENET_SECRET}`).toString('base64')
var config = {
method: 'post',
url: 'https://us.battle.net/oauth/token',
headers: {
'Authorization': `Basic ${encodedAuthorization}`,
...data.getHeaders()
},
data : data
};
The Basic-Auth-Authentication-Scheme functions as follows:
The client provides credentials in the form of a "username" and a "password".
Username and password are concatenated with a colon: "username:password"
The concatenated string is encoded in base64
The header value is then the base64-encoded string prefixed with "Basic "
Below you can see a javascript implementation:
const userName = "username"
const password = "password"
const authenticationHeader = "Basic " + btoa(`${userName}:${password}`)
i want to send a post request using node-fetch with a body payload encoded in the x-www-form. I tried this code but unfortunately it doesnt work:
paypalSignIn = function(){
var username = process.env.PAYPALID;
var password = process.env.PAYPALSECRET;
var authContent = 'Basic '+base64.encode(username + ":" + password);
fetch('https://api.sandbox.paypal.com/v1/oauth2/token', { method: 'POST',
headers: {
'Accept': 'application/json',
'Accept-Language' :"en_US",
'Authorization': authContent,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'grant_type=client_credentials' })
.then(res => res.json()) // expecting a json response
.then(json => console.log(json));
}
I'm not sure if this way is possible but i need to use this standard for die paypal api.
I'm getting statu code 400 with error
grant_type is null
Thx
I don't know if this is the only error, but at the very least you need a space between the word Basic and the encoded username/password.
Next time you ask a question, also post what your script returned. I'm guessing it was a 401 error in this case.
I used the PayPal sandbox today, here is how I managed to get my access token and a successful response (and also answering the OP's question about sending application/x-www-form-urlencoded POST requests with data) =>
I did it with node-fetch but the plain fetch API should work the same.
import fetch from "node-fetch";
export interface PayPalBusinessAccessTokenResponseInterface {
access_token: string;
}
export interface PayPalClientInterface {
getBusinessAccessToken: (
clientId: string,
clientSecret: string
) => Promise<PayPalBusinessAccessTokenResponseInterface>
}
const paypalClient: PayPalClientInterface = {
async getBusinessAccessToken(
clientId: string,
clientSecret: string
): Promise<PayPalBusinessAccessTokenResponseInterface> {
const params = new URLSearchParams();
params.append("grant_type", "client_credentials");
const paypalAPICall = await fetch(
"https://api-m.sandbox.paypal.com/v1/oauth2/token",
{
method: "POST",
body: params,
headers: {
"Authorization": `Basic ${Buffer.from(clientId + ":" + clientSecret).toString('base64')}`
}
}
);
const paypalAPIRes = await paypalAPICall.json();
return paypalAPIRes;
}
};
export default paypalClient;
Im facing an issue to handle the auth0 pop window. Any leads on how do I handle the same.
NOTE :
1. Protractor is what I'm using.
2. Framework : Jasmine (Nodejs).
Attached is the screenshot for the reference.
Screenshot
Thanks,
Zaid
Finally figured out the solution.
I have a javascript that generates the auth0 token. Once the token is generated I use that token and set that to browser cookies along with user credential. This way when I hit the application url which I want to test, the auth0 browser specific authentication prompt isn't displayed.
Below is the code for the same:
var request = require('request');
this.performAuthoLogin = function() {
var defer = protractor.promise.defer();
var credentials = {
"client_id": clientId,
"username": userName,
"password": password,
"id_token": "",
"connection": connectionName,
"grant_type": "password",
"scope": "openid",
"device": "api"
}
request({
url: url,
method: 'POST',
json: true,
body: credentials,
headers: {
'Content-Type': 'application/json'
}
}, function(error, response, body) {
if (error) {
defer.reject(error);
} else {
authTokenId = body.id_token;
console.log(authTokenId);
var profile = {
username: userNameToLogin
email: emailId
}
browser.manage().addCookie("profile", profile, '/', applicationUrl)
browser.manage().addCookie("id_token", authTokenId, '/', applicationUrl);
defer.fulfill(body);
}
});
return defer.promise;
};