AWS Lambda API gives 502 error on POST request - aws-lambda

POST request works fine for Lambda function and API. However, when I hit it through Postman then it gives 502 internal Gateway error.
When I print request in Clouwatch logs for Postman POST request, I get the following:
{
"resource": "/{proxy+}",
"path": "/entitlement",
"httpMethod": "POST",
"body": "ew0KICAgICJsYXN0UmVuZXdhbCI6IDE1MjcxNzY2Njg3OTUsDQogICAgInNvbGRUbyI6ICIwMDAxNjUyNDUzIiwNCiAgICAic3RhcnREYXRlIjogMTUyNzE3NjY2ODc5NSwNCiAgICAiZXhwaXJhdGlvbkRhdGUiOiAxNTI5NzY4NjY4Nzk1LA0KICAgICJhY3RpdmF0aW9uQ29kZSI6ICIxMTExMTExMTExMTExMTExIiwNCiAgICAicXVhbnRpdHkiOiAwLA0KICAgICJ2ZXJzaW9uIjogIjIxOSIsDQogICAgInRlcm0iOiAibW9udGhseSIsDQogICAgImFjdGl2ZSI6IHRydWUsDQogICAgIndlYmtleSI6ICJuZWhhLmNoaW5jaG9yZUBzaWVtZW5zLmNvbSIsDQogICAgInByb2R1Y3RTa3UiOiAiU0U5MTAtSVREIiwNCiAgICAiY3VzdG9tZXJJZCI6IG51bGwsDQogICAgImZpcnN0TmFtZSI6ICJUSElSRCIsDQogICAgImxhc3ROYW1lIjogIlRFU1QiLA0KICAgICJjb21wYW55TmFtZSI6ICJUaGlyZHRlc3QiLA0KICAgICJjYW5jZWxsYXRpb25EYXRlIjogbnVsbCwNCiAgICAiZW1haWwiOiAibmVoYS5jaGluY2hvcmVAc2llbWVucy5jb20iDQp9",
"isBase64Encoded": true
}
When I print request in logs for API Gateway, I get the following:
{
"resource": "/{proxy+}",
"path": "/entitlement",
"httpMethod": "POST",
"body": "{\"lastRenewal\":1532500221761,\"soldTo\":\"0001652453\",\"startDate\":1532500221761,\"expirationDate\":1535178621761,\"activationCode\":\"0449835557734402\",\"quantity\":0,\"version\":\"219\",\"term\":\"monthly\",\"active\":true,\"customerId\":null,\"firstName\":\"THIRD\",\"lastName\":\"TEST\",\"companyName\":\"Thirdtest\",\"cancellationDate\":null,\"email\":\"abc#xyz.com\"}",
"isBase64Encoded": false
}
GET request works fine. Face issue only for POST request.

In 'API-Gateway' console, expand API and select 'Settings' tab.
There is a field for 'Binary Media type', which was set to "*/*', due to which 'isBase64Encoded' is set to true in POST request.
However, my application was posting only json data in request body, so there is no need for 'binary support'. So we removed this field and it worked fine.
If you are posting binary data(images/files), in that case set 'Binary Media type' to respective file support type.

Related

Vue.js Axios Post request blocked

I am trying to build a test app with a vue frontend and a spring boot backend. The backend receive a json from the frontend to register a new user.
But I am struggeling at the point to send a post request from the vue frontend to the backend. I only receive the status Blocked.
So this is the method in vue which should send the post request:
testMethodToClick() {
const data = {
"firstName": "Test",
"lastName": "Tester",
"email": "test.tester#test.de",
"password": "password"
}
const header = {
"Content-Type": "application/json",
"Accept": "*/*"
}
axios.post("http://ptsv2.com/t/ty0mk-1643012780/post");
axios.post("http://localhost:8886/api/v1/registration", data, header);
}
The first post request to ptsv2.com is just to test if the post request generally is working.
But this is the result:
But if I try to test the endpoint with postman, than it works:
So I did something wrong on the vue side.
Does someone know what I am missing?
Thank you very much!

Send recaptcha secret in POST body instead of URL parameters

Server Integration of ReCaptcha works well when I pass values as URL parameters.
{
"success": false,
"error-codes": [
"missing-input-response",
"missing-input-secret"
]
}
The request fails when I pass values as JSON in POST body.
{
"success": true,
"challenge_ts": "2018-10-26T16:01:24Z",
"hostname": "testkey.google.com"
}
Sample code I have seen so far suggests using URL parameters but does not explain why JSON POST body is not supported.
Google's FAQ does not list it either, I am wondering if I am doing something wrong. Is it even possible to request through JSON?
Google's recaptcha api does not support json body. They expect you to send the body as query params.
For example:
POST request.
Body: 'secret=xxxxxxxxxxxxxxxx&response=xxxxxxxxxxxxxxxxxxxxxxxxxx'
Header: 'Content-Type': 'application/x-www-form-urlencoded'

Google Calender Oauth with offline access

I am trying to access the Google Calendar API using VBScript and Oauth offline access. I managed to get a refresh token and an access token, and now I want to get to the step where I actually use the API, using the following code:
sUrl="https://www.googleapis.com/calendar/v3/users/me/calendarList"
sRequest = "access_token="&accesstoken
response=HTTPPost (sUrl, sRequest)
Function HTTPPost(sUrl, sRequest)
set oHTTP = CreateObject("MSXML2.ServerXMLHTTP")
oHTTP.open "POST", sUrl,false
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oHTTP.setRequestHeader "Content-Length", Len(sRequest)
oHTTP.send sRequest
HTTPPost = oHTTP.responseText
End Function
The response I get is :
{
"error": {
"errors": [
{
"domain": "global",
"reason": "authError",
"message": "Invalid Credentials",
"locationType": "header",
"location": "Authorization"
}
],
"code": 401,
"message": "Invalid Credentials"
}
}
This is even though the access token is valid - If I change sURL to https://www.googleapis.com/oauth2/v1/tokeninfo and run the script I get the following response showing a valid token:
{
"issued_to": "...",
"audience": "...,
"scope": "https://www.googleapis.com/auth/calendar",
"expires_in": 2568,
"access_type": "offline"
}
And also if I paste the URL https://www.googleapis.com/calendar/v3/users/me/calendarList?access_token=... into a browser I get a valid response from Google listing the user's calendars
401: Invalid Credentials
Invalid authorization header. The access token you're using is either
expired or invalid.
Access tokens are only good for 1 hour. After the hour is up the access token has expired and you need to use the refresh token to request a new one.
The raw code to get a new acesss token looks something like this. the key is grant_type=refresh_token this tells the authentication server you are requesting a new token.
https://accounts.google.com/o/oauth2/token
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&refresh_token=1/ffYmfI0sjR54Ft9oupubLzrJhD1hZS5tWQcyAvNECCA&grant_type=refresh_token
Your code uses HTTP POST but use an HTTP GET request is required as specified here: https://developers.google.com/google-apps/calendar/v3/reference/calendarList/list. Also, you can provide the access token in the access_token parameter (and not in the oauth_token parameter as suggested in the other answer), but another option is to provide it in an Authorization header as in:
Authorization: Bearer <token>
As an example, a token that returns from:
curl -v https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<token>`
the following introspection result:
{
"issued_to": "<...>.apps.googleusercontent.com",
"audience": "<...>.apps.googleusercontent.com",
"user_id": "<...>",
"scope": "<> https://www.googleapis.com/auth/calendar",
"expires_in": 3527,
"email": "<...>",
"verified_email": true,
"access_type": "offline"
}
can be used in against the Calendar API URL:
curl -v -H "Authorization: Bearer <>" https://www.googleapis.com/calendar/v3/users/me/calendarList
so that it gives me a list of JSON calendar data:
{
"kind": "calendar#calendarList",
"etag": "\"1420511621463000\"",
"nextSyncToken": "00001420511621463000",
"items": [
{
"kind": "calendar#calendarListEntry",
"etag": "\"1418127331044000\"",
...
I managed to figure this out - the calendarList API requires sending an empty body, therefore I change the code to:
set oHTTP = CreateObject("MSXML2.ServerXMLHTTP")
oHTTP.open "GET", sUrl&srequest,false
oHTTP.setRequestHeader "Content-Type", "application/x-www-form-urlencoded"
oHTTP.send
getcal = oHTTP.responseText

How can I insert an interceptor with AngularJS to redirect to login page?

I have a login system that will hold the session for 2 hours. After 2 hours, when the client makes API calls, they get back an error:
{
"Success": false,
"Error": {
"ErrorCode": "002",
"ErrorMessage": "Session expired"
}
}
I need to then redirect the client to /login when that happens. The problem is that I get that error from individual API calls, so rather than change EVERY API call, is it possible to have a global interceptor?
Following the example for Interceptors found here, you can do something like the following in the response section of the interceptor:
response: function(resp){
// resp.data will contain your response object from the server
if(resp.data && !resp.data.Success){
// check for error code
if(resp.data.Error && resp.data.ErrorCode === '002'){
$location.path('/login');
return $q.reject(resp);
}
}
return resp || $q.when(resp);
},
This is assuming that your server is returning a 200 when you get this error message, not on a 401 or 403, but that's what it looks like you're doing. Hope that helps.

YouTube Retrieve a Refresh Token?

I am sending a delete request to the youtube api but I am receiving a 401 error (unauthorized). I'm not sure why. My key is set properly, I am able to access the analytics of the youtube channel. This is my code that fires on a button click
jQuery.ajax({
type: 'DELETE',
// must set api key
url: 'https://www.googleapis.com/youtube/v3/videos?id='+ thisUniqueID + '&key={<?php echo $oAuth2Key; ?>}',
});
I've used alert to check that my auth key is set properly (shown below).
alert('<?php echo $oAuth2Key; ?>');
and I can see in the returned address with the error that the url is proper. What could be the issue?
It looks like I need a refresh token. This is straight out of the docs: The API will return an HTTP 401 response code (Unauthorized) if you submit a request to access a protected resource with an expired access token. The following section explains how to refresh an access token.
Is there an easy way to retrieve a refresh token at the same time that I send a delete request? If not is there an easy way to retrieve one with out the need for the client id/client secret etc.
I somehow have gotten a key for analytics, but when I go to delete a video the key is not valid.
I would suggest you to use Data API v3 instead.
Yes, you can do AJAX calls. Here's the videos->delete call.
DELETE https://www.googleapis.com/youtube/v3/videos?id=VIDEO_ID&key={YOUR_API_KEY}
You find the documentation for using authorization at:
https://developers.google.com/youtube/v3/guides/authentication
You use the API key for access to public data !
Since you want to delete a video, you must use the access_token. An access_token is valid for a short time (1 hour). You can get a new one by using your refresh_token to request another one.
Store a refresh_token since it is valid until it gets revoked.
BTW.
Maybe use client.js, to handle the authorization for your requests ?
For JS, by adding:
<script src="https://apis.google.com/js/client.js?onload=googleApiClientReady"></script>
The general documentation is at:
https://developers.google.com/api-client-library/javascript/start/start-js
An code example for YouTube is at:
https://developers.google.com/youtube/v3/code_samples/javascript
For reference of the video delete method see:
https://developers.google.com/youtube/v3/docs/#videos
The listed methods are: insert, list, delete, update , rate and getRating.
The delete method might be (This is NOT tested with a valid videoID):
var requestOptions = {
id: '012345678901', // replace VIDEOID
part: 'id'
};
var request = gapi.client.youtube.videos.delete (requestOptions);
request.execute(function(response) {
console.log("RESPONSE: " + response);
});
The response using a non-existing videoId is:
[
{
"error": {
"code": -32500,
"message": "Video not found",
"data": [
{
"domain": "youtube.video",
"reason": "videoNotFound",
"message": "Video not found",
"locationType": "parameter",
"location": "id"
}
]
},
"id": "gapiRpc"
}
]

Resources