I have a REST endpoint called myEndpoint that I can successfully hit using Curl like this:
curl \
--request DELETE \
--header "Content-Type: application/json" \
--header "Authorization: JWT eyJhbFciOiJ__FAKE__sInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNhcWliIi__FAKE__9pZCI6NSwiZW1haWwiOiJzYXFpYi5hbGkuNzVAZ21haWwuY29tIiwiZXhwIjoxNDkxNzkyMzEzfQ.feGiXm__FAKE__ZS6V-OROM7EzekRzpu_5pwi865tz8" \
--data '{
"myAttribute": "Something"
}' \
"http://localhost:3999/api/myEndpoint"
However, when my AngularJS code tries to call the same endpoint it fails saying that the mandatory myAttribute parameter was not provided. This is how angularJS is making the call:
var httpParams = {'myAttribute': 'Something'};
$scope.myPromise = $http.delete('http://localhost:3999/api/myEndpoint', httpParams).then(self.myEndpointSuccess, self.myEndpointFailure);
(AngularJS's attachment of the JWT token to the HTTP request is not shown, but I'm sure that is working)
How can I see exactly what HTTP request AngularJS is sending so that I can do an apples-to-apples comparison agains my working curl call?
Here is my Chrome's Developer Tools -> Network tab. I don't see the information I'm seeking there:
The $ http service documentation says that $ http.delete gets two parameters, URL and config. By its call curl, I understand that myAtribute is the name given to a parameter that you want to send to the endpoint, in which case it should be in the params property or data property of the config object.
angular reference
another question
FYI, DELETE requests do not typically have a request body.
As for your issue, RTFM; the second arg to $http.delete should be a config object, so in your case
$http.delete('http://localhost:3999/api/myEndpoint', {data: httpParams})
AngularJS provides the $http module for http requests. You can make a specific request with this module and then process the request with the . then() whichever takes a success callback followed by a error callback
Related
I'm trying to throttle the number of requests a client can make to my translator service which uses Azure Translation API.
The following link from Microsoft describes how to limit requests, but it's not clear where in the request this throttling information should be added. I assume the request headers?
https://learn.microsoft.com/en-us/azure/api-management/api-management-sample-flexible-throttling
Here is the curl. Note the rate limiting headers at the end. Is this the way to do it?
// Pass secret key and region using headers to a custom endpoint
curl -X POST " my-ch-n.cognitiveservices.azure.com/translator/text/v3.0/translate?to=fr" \
-H "Ocp-Apim-Subscription-Key: xxx" \
-H "Ocp-Apim-Subscription-Region: switzerlandnorth" \
-H "Content-Type: application/json" \
-H "rate-limit-by-key: calls=10 renewal-period=60 counter-key=1.1.1.1" \
-d "[{'Text':'Hello'}]" -v
The link you've shared is from API Management, a managed API Gateway available on Azure. The idea is to generate "products" and let your users to subscribe to them. This way, you'll be able to track the requests and perform the throttle using a rate limit policy (the link you've shared).
if needed, please watch this quick video showing this functionality in use:
https://www.youtube.com/watch?v=dbF7uVkGOw0
I am trying to make a POST request to an AWS Lambda Python Script I have set up.
I have already heard about solving the issue of Access-Control-Allow-Origin by adding a header to the Response from AWS lambda, that looks like Access-Control-Allow-Origin:*, and I implemented this in the code I was working on for the get request. Then when I begun creating a POST request, I did the same thing, so that the new POST request originally looked like this:
def post(event, context):
try:
return dict(
statusCode=200,
headers= {'Access-Control-Allow-Origin': "*"},
body="test"
)
except Exception as ex:
return dict(
statusCode=500,
body=str(ex)
)
And this works, in Chrome's Network-Tab I see that we pass a post request and there is no issue, and the header is recognized properly, allowing Cross-Origin calls. But this is pretty much just the GET request I have which is already set up and working. So when I update it to be more similar to a POST METHOD and do what I want the problems begin.
So my code, that I want to be performed in the POST request is simple, I should be able to make the request like such,
def post(event, context):
try:
result=str(event.get("inputOne") + event.get("inputTwo"))
return dict(
statusCode=200,
headers= {'Access-Control-Allow-Origin': "*"},
body=result
)
except Exception as ex:
return dict(
statusCode=500,
body=str(ex)
)
When I test this in the AWS Lambda Management console, my code works, and I get the expected response back in the body.
But then when I try and call the POST endpoint from my React Site, I once again am getting the error:
Access to XMLHttpRequest at 'THE_POST_URL' from origin
'http://localhost:XXX' has been blocked by CORS policy: No 'Access-
Control-Allow-Origin' header is present on the requested resource.
So for some reason, when the body variable is not just a simple string in quotes like "this" <- it fails. I believe this has to do with the Content-Type in the request being of the form application/json;charset=UTF-8 while my request only accepts (as it says in dev-tools) application/json however even when trying to add the headers to accept this format for content-type, I am still getting the same issues.
I am not entirely sure why the header worked on the GET request, but not the POST request, and would appreciate anyone being able to help teach me, thank you!
EDIT: I have also tried adding 'Access-Control-Allow-Methods': "OPTIONS,GET,POST" to the headers of the post response, but this did not work either.
So after reading through the comments on my question, I decided it was worth going and taking a harder look at the way I had my API Gateway, and Lambda service set up on AWS.
I began using the curl utility in order to try and test my post-call from a terminal utility and found that there it was also failing, but I was able to use CloudWatch to debug, the issue and finally get it working.
The problem that I was facing with my curl Request was that I was not properly formatting the JSON input, but even when I was the Lambda was transforming the event improperly, not resulting in a Dict, as expected.
The curl call I was using can be seen:
curl -X POST https://myURL.execute-api.myREGION.amazonaws.com/stage/yourPOST \
-d '{"inputOne":80000,"inputTwo":85}'
But in order to read that input properly, and then work with it, I had to update my code in the Lambda to reflect parsing the input properly, this updated lambda code can be found here. The event object that you are passing to this lambda is a DICT object, so on the first line, we use JSON.loads to decode the "body" value of the event, into a dict that we store as body. Then to get the value of the two attributes, we use the command body.get("yourKey").
def yourPOST(event, context):
body=json.loads(event["body"])
a=body.get("inputOne")
c=body.get("inputTwo")
After making these changes the call from my React site works without error! If anyone has any questions feel free to comment, I hope this helped!
I'm using the Yelp's Fusion API.
All the documentation is here and seems straight forward but still doesn't seem to work.
https://www.yelp.com/developers/documentation/v3/get_started
Here is my request for a token.
https://api.yelp.com/oauth2/token?grant_type= OAuth2&client_secret= SECRET&client_id=ID
I receive this response.
{
"error": {
"description": "Bad Request",
"code": "CLIENT_ERROR"
}
}
I reread the documentation and it says
"To get an access token, make a POST call to the following endpoint
using the client id and secret obtained from the former step. Then get
the access token from the response body."
I submitted this
https://api.yelp.com/oauth2/token?client_id=ID&client_secret= SECRET
I got the same error.
What am I missing?
Thank you in advance
You have three problems that are causing you to get the bad request
You have spaces in your parameter values
?grant_type= OAuth2
You are using the wrong grant_type. On the documentation page they specify that only client_credentials is supported, meaning you have to use that as the value
grant_type string The OAuth2 grant type to use.
Right now, only client_credentials is supported.
You are using the wrong request method, it has to be a POST not a GET request
These parameters should be sent in application/x-www-form-urlencoded
format in the POST call.
Note that https://api.yelp.com/oauth2/token?client_id=ID&client_secret=SECRET is still sending your parameters as GET parameters as they are in the url query string. You have to pass the parameters as POST fields, and the syntax for doing so differs on the server side script language you use.
Also your request needs to be done server side as the /oauth2/token endpoint does not send a Access-Control-Allow-Origin header meaning you cannot use an ajax request to get the data.
So if say you were using PHP server side, you could use CURL to get the token
$postData = "grant_type=client_credentials&".
"client_id=YOURCLIENTID&".
"client_secret=SECRET";
$ch = curl_init();
//set the url
curl_setopt($ch,CURLOPT_URL, "https://api.yelp.com/oauth2/token");
//tell curl we are doing a post
curl_setopt($ch,CURLOPT_POST, TRUE);
//set post fields
curl_setopt($ch,CURLOPT_POSTFIELDS, $postData);
//tell curl we want the returned data
curl_setopt($ch,CURLOPT_RETURNTRANSFER, TRUE);
$result = curl_exec($ch);
//close connection
curl_close($ch);
if($result){
$data = json_decode($result);
echo "Token: ".$data->access_token;
}
I used POSTMAN to get the data required, you can download it here -
https://www.getpostman.com/
In order to obtain your access token the parameters should be in the request body, not the request URL.
In POSTMAN you need to provide the following as key/value pairs:
grant_type : client_credentials is supported.
client_id : The client id for you app with Yelp.
client_secret : The client secret for you app with Yelp.
To do this, you enter them in the Body. Also click the x-www-form-urlencoded radio button.
See the screenshot link below:
How to configure POSTMAN to get your Yelp Access Token
You can then play around over at RapidAPI Yelp API to test some endpoints and parameters.
I am making a Chrome Extension that talks to a website via an api. I want it to pass information about a current tab to my website via a cors request.
I have a POST api request already working. It looks like this:
...
var url = "https://webiste.com/api/v1/users/sendInfo"
...
xhr.send(JSON.stringify({user_name:user_name, password:password, info:info}));
Its corresponding curl statement is something like this:
curl -X POST https://website.com/api/v1/users/sendInfo -d '{ username:"username", password:"password", info: "Lot's of info" }' --header "Content-type: application/json
But, this is not as secure as we want. I was told to mirror the curl command below:
curl --basic -u username:password <request url> -d '{ "info": "Lot's of info" }'
But, one cannot just write curl into javascript.
If someone could either supply javascript that acts like this curl statement or explain exactly what is going on in that basic option of the curl script I think that I could progress from there.
The curl command is setting a basic Authorization header. This can be done in JavaScript like
var url = "https://webiste.com/api/v1/users/sendInfo",
username = "...",
password = "...";
xhr.open('POST', url, true, username, password);
xhr.send(...);
This encodes the username/password using base 64, and sets the Authorization header.
Edit As arcyqwerty mentioned, this is no more secure than sending username/password in the request body JSON. The advantage of using the basic authentication approach is that it's a standard way of specifying user credentials which integrates well with many back-ends. If you need security, make sure to send your data over HTTPS.
curl is the curl binary which fetches URLs.
--basic tells curl to use "HTTP Basic Authentication"
-u username:password tells curl supply a given username/password for the authentication. This authentication information is base64 encoded in the request. Note the emphasis on encoded which is different from encrypted. HTTP basic auth is not secure (although it can be made more secure by using an HTTPS channel)
-d tells curl to send the following as the data for the request
You may be able to specify HTTP basic authentication in your request by making the request to https://username:password#website.com/api/v1/users/sendInfo
I am reading from the Stripe documentation that I can charge an user with the following curl request:
Definition
POST https://api.stripe.com/v1/charges
Request
curl https://api.stripe.com/v1/charges \
-u sk_test_PjPAEVD1LXfUuA6XylJPnQX4: \
-d amount=400 \
-d currency=eur \
-d source=tok_16ffrPHW84OuTX9VFTYguruR \
-d description="Charge for test#example.com"
In an Angular setting, I presume that I have to use $http. However, how do you pass on the parameters?
I tried the following
$http.post('https://api.stripe.com/v1/charges', result)
.success(function(data, status, headers, config) {
alert("success", data);
})
.error(function(data, status, headers, config) {
alert("error", data);
});
but received the error:
XMLHttpRequest cannot load https://api.stripe.com/v1/charges. No
'Access-Control-Allow-Origin' header is present on the requested
resource.
You need to have some code running server-side (perhaps using PHP, Ruby, Node.JS, ASP.NET, etc etc etc) that takes the token you generated in the browser/Javascript as input, and sends it to https://api.stripe.com/v1/charges to make the charge.
You must not make that call from the front-end (browser) Javascript/Angular. By doing so, you are putting your secret key out in public – your Stripe account would no longer be secure. The only key that should ever feature in your front-end code is the public key, which can only be used for making tokens.
Take a look here for instructions on generating the token and sending it to the server, and here for instructions on creating the charge server-side.