Rapidapi & 401 unauthorized Response - delphi

I am working with Rad Studio (Delphi) and I am trying to connect to a RapidApi Endpoint via a Rest Component of Rad Studio.
Although I use the "x-rapidapi-key" & "x-rapidapi-host" as parameters on the Rest Component, I get a 401 unauthorized Response.
Any Ideas?
Thank you

It's unclear but probably you need to pass x-rapidapi-host and x-rapidapi-key as the request headers, not parameters.
For example, try something like this
var axios = require("axios").default;
var options = {
method: 'GET',
url: 'https://example.p.rapidapi.com/',
params: {query: 'something here'},
headers: {
'x-rapidapi-host': 'example.p.rapidapi.com',
'x-rapidapi-key': '12345'
}
};
axios.request(options).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.error(error);
});

Related

Getting Error: XMLHttpRequest error when using dart

I have tried POST request from dart code to django rest api on local machine.
the API works when I do POST from Postman but fails when using dart.
Can someone please explain why !
my dart code :
void post_call() async {
var headers = {
'Content-Type': 'application/json',
};
var data = {"_selectedValue":"yes","_DescriptionValue":"yes","_namefieldValue":"yes","_contactValue":"yes","_emailValue" : "yes"};
var url = Uri.parse('http://127.0.0.1:8000/first_app/forms/');
var res = await http.post(url, headers: headers, body: json.encode(data));
if (res.statusCode != 200) throw Exception('http.post error: statusCode= ${res.statusCode}');
print(res);
}
the API works when I do POST from Postman but fails when using dart.

Get OAuth 2.0 Token from personnal accounts (Outlook)

I am trying to use #azure/msal-node on a node backend server. 
all work fine for business accounts onmicrosoft.com but not for personnal accounts like outlook.com
according to this documentation, Authentication seems to be possible
https://learn.microsoft.com/en-us/exchange/client-developer/legacy-protocols/how-to-authenticate-an-imap-pop-smtp-application-by-using-oauth
But i don't understand if my problem come from azure AD configuration or from my code. 
exp.post('/connect', function (req, res) {
let authCodeUrlParameters = {
scopes: SCOPES_OUTLOOK,
redirectUri: "http://localhost:4220/redirect",
};
publicMicrosoftClient.getAuthCodeUrl(authCodeUrlParameters).then((response) => {
if (req.body.email) {
response += `&login_hint=${req.body.email}`
}
open(response)
}).catch((error) => console.log(JSON.stringify(error)));
});
exp.get('/redirect', async function (req, res) {
try {
const form = {
'code': req.query.code,
'client_id': CLIENT_ID_OUTLOOK,
'scope': SCOPES_OUTLOOK.join(' '),
'redirect_uri': 'http://localhost:4220/redirect',
'grant_type': 'authorization_code',
'client_secret': encodeURI(SECRET_VALUE_OUTLOOK),
}
const options = {
url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
method: 'post',
}
response = await got(options, { form });
respToken = response.body
...
} catch (error) {
console.log(error)
res.end();
}
});
the error come from ...v2.0/token request. the server response doesn't really help (error 400 bad request)
in azure AD we have app registered and all required scope with status granted.
Thank you in advance for your help,
Yan
• You are getting this error because you have not allowed or selected ‘Accounts in any organizational directory (Any Azure AD directory - Multitenant) and personal Microsoft accounts (e.g. Skype, Xbox)’ as shown below in the snapshot for the Azure AD app registered regarding authentication for your backend code: -
• Also, if you have already configured your Azure AD application registration for your node backend code, then you can also configure the above in your Azure AD app’s ‘Application Manifest’ by modifying the parameter ‘signInAudience’ with the value as ‘AzureADandPersonalMicrosoftAccount’ as well as ensure that the below parameters are also set as per the stated values to resolve this issue: -
“allowPublicClient” : true
“accesstokenAcceptedVersion” : 2
For more information regarding this, kindly refer to the below link: -
https://learn.microsoft.com/en-us/azure/active-directory/develop/reference-app-manifest

Microsoft Graph API Unauthorized Error 401

I am new to MS graph api. I am learning this API and I followed this tutorial https://learn.microsoft.com/en-us/azure/active-directory/develop/tutorial-v2-nodejs-console and it works fine for me when retrieving the user. here is the code
async function main() {
try {
// here we get an access token
const authResponse = await auth.getToken(auth.tokenRequest);
console.log("get auth reespones ", authResponse)
const options = {
method: 'get',
headers: {
Authorization: `Bearer ${authResponse}`
}
};
// call the web API with the access token
const users = await fetch.callApi(auth.apiConfig.uri, options);
console.log("get users ", users)
} catch (error) {
console.log("error here",error);
}
};
But I am trying to call other API and I have a problem accessing the calendar API.
here is the new function I use to call the calendar api in ms graph.
async function getcalendar() {
try {
// here we get an access token
const authResponse = await auth.getToken(auth.tokenRequest);
const options = {
method: 'get',
headers: {
Authorization: `Bearer ${authResponse}`,
Prefer: `outlook.timezone="Pacific Standard Time"`
}
}
// call the web API with the access token
const users = await fetch.callApi('https://graph.microsoft.com/v1.0/me/calendar', options);
console.log("get users ", users)
} catch (error) {
console.log("error is here ",error);
}
};
in my application in azure I already set all the permissions
I have no idea why it keeps saying unauthorized.
Any help is appreciated. Thank you
Try to set Calendars.Read, Calendars.ReadWrite for Delegated permission type instead of Application type.
getSchedule api doesn't support personal Microsoft account.
You cannot use personal accounts to hit the me/calendar/getschedule because this is not supported.
The permissions works only for work or school accounts or with App token.
As you are using Application context you need to make the call something like below.
/users/{id|userPrincipalName}/calendar/getSchedule as there is no meaning for me if there is no user involved.

IBM DataPower - How to handle HTML Response from openurl?

I tried looking for the solution in the forum but I was unable to find something similar to what I'm trying to achieve. I have a gateway script in an MPG which kinda looks like this:
session.INPUT.readAsJSON(function (error, json) {
if (error){
throw error;
} else {
var SAMLResponse = json['SAMLResponse'];
var RelayState = json['RelayState'];
var urlopen = require('urlopen');
var options = {
target: 'https://************.com/e32d32der2tj90g8h4',
method: 'POST',
headers: { 'HEADER_NAME' : 'VALUE'},
contentType: 'application/json',
timeout: 60,
sslClientProfile: 'ClientProfile',
data: {"SAMLResponse": SAMLResponse, "RelayState": RelayState}
};
urlopen.open(options, function(error, response) {
if (error) {
session.output.write("urlopen error: "+JSON.stringify(error));
} else {
var responseStatusCode = response.statusCode;
var responseReasonPhrase = response.reasonPhrase;
response.readAsBuffer(function(error, responseData){
if (error){
throw error;
} else {
session.output.write(responseData);
console.log(responseData);
}
});
}
});
}
});
I'm doing a POST request and the response I get from the urlopen function is an HTML page, how to I display the contents of that page in my browser? I need that to initiate a process flow. am I going in the wrong direction here? what's the best way to POST to a URI and display it's response in DataPower?
with regards to my experience with DataPower, I just started learning, So I might not be familiar with many of the concepts.
Thanks in Advance!
session.INPUT.readAsJSON() would indicate that you are receiving JSON data as the input (from the POST).
Since you are building this in a Multi-Protocol Gateway (MPGW) you need to set the Response type to non-xml if the response is HTML and if there is no backend call being made (other than the url-open()) you also must set the skip-backside=1 variable.
Is the scenario as:
JSON HTTP Request -> [MPGW] -> url-open() -> Backend server --|
HTTP Response <-----------------------------------------|
Or:
JSON HTTP Request -> [MPGW] -> url-open() --| (skip-backside)
HTTP Response <------------------------|
If there is no backend call I would recommend building this in a XML Firewall (XMLFW) service instead and set it to "loopback" and non-xml.
If there is a backend and that is where you are sending your HTML from the url-open() then only MPGW Response type needs to be set to non-xml.
If it is the second option the you can just set the payload and headers in GWS and just call the target (https://************.com/e32d32der2tj90g8h4) as teh MPGW backside connection, no need for the url-open().

$http error handling in AngularJS

$http in my AngularJS project not able to recognize 40X(401,403,405...) errors on iOS.
I am using 1.2.10 AngularJS version and Cordova version 3.4.0.
Below is the code I am using:
TE_SERVICES.factory('hello',function ($http,$rootScope) {
return {
loginUser: function(userCredentials,successCallback,errorCallback){
$http({
method: "GET",
url: "data/example.json",
headers: {"Authorization":'Basic '+userCredentials},
}).then(function(response){
successCallback(response.data);
console.log("Success------"+JSON.stringify(response))
},function(data, status, headers, config){
errorCallback(data);
console.log("Error------"+JSON.stringify(data)+" "+status)
})
}
}
});
hello.loginUser($rootScope.encodedUserCredencials,function(persons) {
// success handler
}, function(data) {
// error handler
console.log(data.status+"===="+status)
});
data.status is returning 0 and status returns undefined.
Please help me to resolve this issue.
Tried to include the domain in whitelist on IOS.But no solution :( It still gives the same response.
But the same code works absolutely fine in Android.
Please help me to resolve this issue.
Thanks in advance :)
So you r using the $http from angular. Do you use the error callback or the second function in the then callback ?
Example
$http.get("someUrl")
.success(function(response){}) // if http code == 200
.error(function(response){}) // else
Or with then, that can take 2 functions. The first is the onSuccess, the second the onError function.
$http.get("someUrl")
.then(function(response){
// if http code == 200
},
function(response){
// else
});
The response parameter does also contain the error codes.
Consider using a $httpInterceptor to handle all errorcodes at the same place, instead handling them in every http callback.
UPDATE:
It seems, that the angular doc is incomplete/wrong for the success callback.
It doesnt pass 4 parameter there. It does pass a response object that contains all the information about request+response and the passed data.
Update to the edit:
Dont write callbacks by yourself. Use angular promises:
TE_SERVICES.factory('hello',function ($http,$rootScope) {
return {
loginUser: function(userCredentials){
return $http({
method: "GET",
url: "data/example.json",
headers: {"Authorization":'Basic '+userCredentials},
}).then(function(response){
return response.data;
},function(response){
return response;
});
}
}
});
hello.loginUser($rootScope.encodedUserCredencials)
.then(function(persons) { // success handler
}, function(data) { // error handler
console.log(data);
});
Try this and tell me if the console.log logs something.
I had exactly the same problem. Cordova app, angular js, IPhone and 401 requests are not received in angular js http interceptor. They work fine on android devices.
My finding was that IPhone browser is handling those at a higher lever and trying to use WWW-Authenticate information to do authentication. This is why the response does not get to angular.
The only solution I found, was to change my service to return 400 instead of 401 in case of an api request. In this case I return 400 with an error message that I handle on client side.
I hope this helps.
My issue with the 403 status code was that my backend returned a response with status 403 but the body of a response did not contain a JSON string. It contained just a string - Authentication Failed.
The rejection variable was an object Error.
I encoded the body and the rejection variable contains a valid response error object.
To handle HTTP errors I use interceptors.
$httpProvider.interceptors.push(function($q, $location, redirect, HTTP_CODES) {
return {
'responseError': function(rejection) {
if (rejection.status === HTTP_CODES.FORBIDDEN) {
redirect('/login', $location.url());
}
return $q.reject(rejection);
}
};
});

Resources