Angular2 post with mailchimp - http

My post works in postman but doesn't work inside my app. What am I doing wrong?
let data = obj;
let url = 'https://us123.api.mailchimp.com/3.0/lists/{somenumber}/members';
let username: string = 'user';
let password: string = 'mytokenhere';
let headers = new Headers();
headers.append("Authorization", "Basic " + btoa(username + ":" + password));
headers.append("Content-Type", "application/x-www-form-urlencoded");
return this._http.post(url, data, {headers: headers}).subscribe(
data => this.response(data),
error => this.response(error)
);
I'm getting a CORS error in app:
'XMLHttpRequest cannot load https://us123.api.mailchimp.com/3.0/lists/{{somenumber}}/members. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 501.'

Mailchimp doesn't support client side calls to their API. What you would need to do is setup a server that can proxy the requests from the browser to Mailchimp. There isn't much you can do client side to get it to work if the Mailchimp API doesn't provide the CORS response headers.
If your API that you create is on the same domain as the website, then the CORS issue would be eliminated (or you can also fix by setting the appropriate headers)
See the note under Authentication:
https://developer.mailchimp.com/documentation/mailchimp/guides/get-started-with-mailchimp-api-3/
More Info:
https://www.moesif.com/blog/technical/cors/Authoritative-Guide-to-CORS-Cross-Origin-Resource-Sharing-for-REST-APIs/

Related

Xamarin.Forms HttpClient send get request using a simple fourSquare API-KEY

I am trying to get a connection to the Places AIP of foursquare. (https://developer.foursquare.com/reference/place-search)
This needs me the send the following authorization header:
{ "Authorization" : "<API_KEY>"} and not { "Authorization" : "<SOME_SCHEMA> <API_KEY>"}
SOME_SCHEMA being "Basic", "Key" or any other type.
--header 'Authorization: API_KEY'
I tried to set is like so
client.DefaultRequestHeaders.Authorization = new
AuthenticationHeaderValue(Constants.API_KEY);
According to MSDN documentation this should work. but all I get is an exception saying that the header type is invalid..
Spend the day trying to found a way. but nothing I tried so far works.
I did text over curl and my api-key is good and so is the request. I really just need to get the HttpClient to accept not having a schema/type for Authorization.
This works.
it will allow to have a authorization header that does not contain an auth type.
var request = new HttpRequestMessage(HttpMethod.Get, url);
request.Headers.Add("Accept", "application/json");
request.Headers.TryAddWithoutValidation("Authorization", Constants.API_KEY);

Microsoft Graph 'Unable to read JSON request payload' error when inviting users to Azure AD in Python with Requests

I'm trying to automate inviting users to an Azure AD using the MS Graph API but get an 'Unable to read JSON request payload' error.
I'm pulling data from a ticketing system, retrieving the current AAD users and diff-ing both. Then I'll be pushing the new ones into the AAD and updating them to include them in an Attendees AD Security group.
I created a Python Azure Function that calls the Graph API with Requests :
def insert_users(users_emails):
logging.info('Inserting new users in AAD')
token = generate_auth_token()
users_emails = users_emails[:2]
added_attendees = []
for email in users_emails:
req_body = {
"invitedUserEmailAddress" : email
, "inviteRedirectUrl" : "https://myapp.com"
}
body_length = sys.getsizeof(req_body)
req_headers = {
'Authorization' : 'Bearer {0}'.format(token)
, 'Content-Type' : 'application/json; charset=utf-8'
, 'Content-Length' : str(body_length)
}
response = requests.post(
'https://graph.microsoft.com/v1.0/invitations'
, headers = req_headers
, data = req_body
)
response = response.json()
logging.info(response)
added_attendees.append(email)
return added_attendees
The Graph API sends back the following error message :
{'error':
{'code': 'BadRequest',
'message': 'Unable to read JSON request payload. Please ensure Content-Type header is set and payload is of valid JSON format.',
'innerError':
{'request-id': '4ff5332d-d280-4b0d-9e04-a7359ab0e2fb', 'date': '2020-05-27T14:51:18'}
}
}
I tried adding the charset to the Content-Type header but it won't work. I read someplace the Content-Length could be useful so I added it too, to no avail.
Tests run ok in Postman and I'm already performing a POST request against the Azure AD API to get an Access Token so the Requests JSON body is parsed fine then. I also tried using single or double quotes in the JSON payload but it didn't work either.
My take is something is misinterpreted by the Graph API but I can't figure out what.
Thanks forward for your help !
i found a solution. Instead of passing a data argument to the request.post method, I passed a json= argument
response = requests.post(
'https://graph.microsoft.com/v1.0/invitations'
, json={'invitedUserEmailAddress':email,'inviteRedirectUrl':'https://myapp.com'}
, headers = req_headers
)

How to pass additional parameter when requesting for token

I am trying to get access token from azure AD, however one additional parameter
resource is not present when request is send to /oauth2/token endpoint
Is it possible somehow to add additional parameter? I cannot find any class to override
AADSTS50001: Resource identifier is not provided
c.AddSecurityDefinition("oauth2", new OAuth2Scheme
{
Type = "oauth2",
Flow = "accessCode",
AuthorizationUrl = $"https://login.microsoftonline.com/{_configuration["Auth:Tanent:TanentId"]}/oauth2/authorize",
TokenUrl = $"https://login.microsoftonline.com/{_configuration["Auth:Tanent:TanentId"]}/oauth2/token",
});
Example request
// Line breaks for legibility only
POST /{tenant}/oauth2/token HTTP/1.1
Host: https://login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&client_id=2d4d11a2-f814-46a7-890a-274a72a7309e
&code=AwABAAAAvPM1KaPlrEqdFSBzjqfTGBCmLdgfSTLEMPGYuNHSUYBrqqf_ZT_p5uEAEJJ_nZ3UmphWygRNy2C3jJ239gV_DBnZ2syeg95Ki-374WHUP-i3yIhv5i-7KU2CEoPXwURQp6IVYMw-DjAOzn7C3JCu5wpngXmbZKtJdWmiBzHpcO2aICJPu1KvJrDLDP20chJBXzVYJtkfjviLNNW7l7Y3ydcHDsBRKZc3GuMQanmcghXPyoDg41g8XbwPudVh7uCmUponBQpIhbuffFP_tbV8SNzsPoFz9CLpBCZagJVXeqWoYMPe2dSsPiLO9Alf_YIe5zpi-zY4C3aLw5g9at35eZTfNd0gBRpR5ojkMIcZZ6IgAA
&redirect_uri=https%3A%2F%2Flocalhost%3A12345
&resource=https%3A%2F%2Fservice.contoso.com%2F
&client_secret=p#ssw0rd
//NOTE: client_secret only required for web apps
&resource is not being send by default, and i want to add it somehow.

Calling AWS API Gateway from distant webclient using CORS

On AWS, I built a Lambda function which is exposed on the web using API Gateway.
Access to the API is secured by Amazon Cognito.
My problem is I can't send a request to this API from a client hosted at test.mydomain.com, even after I successfully authenticate on Cognito (thus sending the required token in the request header).
The code I use on my web client to send the request to API Gateway endpoint:
function ajaxPost(url, data, callback) {
var req = new XMLHttpRequest();
req.open("POST", url);
req.addEventListener("load", function () {
if (req.status >= 200 && req.status < 400) {
callback(req.responseText);
} else {
console.error(req.status + " " + req.statusText + " " + url);
}
});
req.addEventListener("error", function () {
console.error("URL " + url + " unreachable.");
});
req.setRequestHeader("Content-Type", "application/json");
req.setRequestHeader("Authorization", data.get("id-token"));
data = JSON.stringify(data);
req.send(data);
}
I enabled CORS on the API method via AWS console, and also on my browser for testing, so cross-domain requests should be allowed.
EDIT
After adding Access-Control-Expose-Headers in the API Gateway CORS config,
the error message I get from the Chrome console is: "XMLHttpRequest cannot load https://XXXX.execute-api.us-east-1.amazonaws.com/prod/RessourceName. Response for preflight has invalid HTTP status code 401" and I can see "x-amzn-errortype:UnauthorizedException" in the OPTIONS response Header.
It's been a few days now, and after looking at every API Gateway tutorials and config, I'm still stucked... Any help would be appreciated, thanks a lot!
Solved!
Apparently, there would be a bug in AWS, where enabling/editing CORS after the API has been deployed would do nothing.
See SO response here: https://stackoverflow.com/a/40733680/7717871
I tried creating a new API from AWS Console, enabling CORS at the very beginning of the process, and then deploying the newly created API: it worked.

Angular2 : detect error from HTTP post

I cannot interecept error from http post
a part of my mservice (http post method)
addApplicationLink(applicationLink: ApplicationLink){
let body = JSON.stringify(applicationLink);
let requestHeaders = new Headers();
var headers = new Headers();
headers.set('Content-Type', ['application/json; charset=utf-8']);
let reqoptions = new RequestOptions({
headers: headers
});
return this._http.post(this._applicationLinksUrl + this._linkServicePath,body,{headers: headers});
in my component :
addApplicationLink() {
//todo
this.addNewLink = false;
/* check if must be done after call real rest service */
//this.applicationLinks.push(this.applicationLinkAdd);
this._applicationLinkService.addApplicationLink(this.applicationLinkAdd)
.subscribe(data => {
this.applicationLinks.push(this.applicationLinkAdd)
},
error => {
// handle error
console.error('this an erreor ' + error.status)
}
)
When user tries to add two same applicationlinks , the backend returns an error 409
But when I execute , error.status displays 200 in browser console
I see also in browser console
XMLHttpRequest cannot load http://localhost:7001...... No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 409.
rem : Http post is made with json , thus there is a prefligth call
Have you an idea to intercept error 409 ?
In fact, your server doesn't send back the CORS header (Access-Control-Allow-Origin' header is missing). This prevent the browser from providing the actual 409 error to the Angular2 application within the browser.
You need to fix first the problem on the server and you will be able to see this 409 error.
For more details about how CORS works, you could have a look at this article:
http://restlet.com/blog/2015/12/15/understanding-and-using-cors/

Resources