I've got an API gateway v2 which is using a proxy integration to lambda.
I'm trying to pass a custom header value via a GET call to my API.
...
fetch(new Request(refreshUrl, {
method: 'GET',
headers: new Headers({
'refreshToken': user?.tokens.refreshToken
})
}))
...
I can't for the life of me figure out how to get APIGW to pass that header value to my lambda. When I log the event received in my lambda, my "refreshToken" header is nowhere to be seen.
I've tried to add parameter mapping such as the following to my lambda integration in apigw with no success:
$request.header.refreshtoken
And the documentation for such scenarios with AWS only seems to show for APIGW v1.
Solved:
The issue wasn't related to APIGW. The request parameter mapping is correct.
The problem was that I was proxying the api via cloud front and I needed to whitelist the header in my distribution.
Related
I have a google cloud api gateway deployed to send requests to a cloud run service.
The cloud run service hosts a laravel docker container image and to authenticate with my authenticated pages, I need to send an Authorization header (Authorization: Bearer my-user-token-here).
When I send the request directly to the cloud run service, I am able to get the response I need with the Authorization header set. But, when I send the request through the api gateway, I always get an unauthenticated message showing the header is missing in the api request to the cloud run. I am not sure of this though.
I can't find any useful documentation on google cloud api gateway to suggest whether cloud run drops the header.
I am also not sure whether the error is from the openapi.yaml. So far I realized I cannot use the v3 of the openapi documentation but rather v2 as api gateway does not support v2. In the v2 of the openapi docs, the securityDefinitions don't support Authorization header Bearer token but instead supports Authorization header basic.
My Openapi yaml
# openapi2-run.yaml
swagger: "2.0"
info:
title: my-api
description: my custom api
version: 1.0.0
schemes:
- https
produces:
- application/json
consumes:
- application/json
x-google-backend:
address: https://some-cloud-run-url
basePath: /api
host: my-api.nw.gateway.dev
x-google-endpoints:
- name: "my-api.nw.gateway.dev"
allowCors: True
paths:
/user:
get:
summary: Requested user details.
operationId: UserDetails
responses:
"200":
description: Return Requested User Details.
schema:
type: string
"default":
description: Unexpected error
The surprising fact is that if I send the request either locally or directly to the cloud run, it works and I get no authentication error, but when I use the api-gateway, then I get the error. So I am guessing it has to do with the header going missing when the request reaches the cloud run, probably because the yaml definition I have here does not have an authorization header.
We have an API gateway instance which sends requests to cloud functions.
If any incoming requests have an Authorization header, the gateway maps the header details into an X-Forwarded-Authorization header in the request to the cloud function.
I assume it's the same for requests to Cloud Run. I don't have any experience with Laravel to know if it has options to look in the forwarded header, though.
Actually you can ignore it by setting the disable_auth in x-google-backend.
The document is not in google gateway, but in google endpoint as follow.
https://cloud.google.com/endpoints/docs/openapi/openapi-extensions
By the document it said:
When configuring your target backend, you may not want to use IAP or IAM to authenticate requests from ESPv2 if either of these conditions apply:
The backend should allow unauthenticated invocations.
The backend requires the original Authorization header from the API client and cannot use X-Forwarded-Authorization (described in the jwt_audience section).
So in your particular case, you just need to modify a single block like this:
x-google-backend:address:
https://some-cloud-run-url
disable_auth: True
And it will work like a charm.
Beware that once you decide to do the authorization yourself, you cannot set the securityDefinitions in the gateway config. The gcp gateway will throw 401 if you do this.
We have a simple application structure that our ReactJs front-end make request to api gateway which does a proxy-integration with a lambda function. Since our api gateway is passing requests as they are without any modification and do the same when returning responses to customer so the place we are going to add http security headers would be in the lambda function itself. I have done some research on how it can be achived but all the answers I got searching in Google mention lambda#Edge+Cloudfront similar to this post which we do not use at all, does it mean we have to change our structure by adding these two things? Thanks.
The article you reference assumes the backend is static (e.g. S3) and cannot set headers. That's why Lambda#Edge is used.
It sounds like your current setup should work without any changes... Did you try adding headers in the code?
I have this code working perfectly for the APIGW + Lambda (proxy integration) combo.
exports.handler = async function (event) {
var response = {
statusCode: 200,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-My-Header': 'whatever'
},
body: JSON.stringify({status: 'OK'}),
}
return response
}
Add HSTS header in AWS Lambda.
I am trying to set up an API Gateway to call another lambda function that will upload an image to S3. The feature works well when I am using an app like POSTMAN, however when I run the browser using React I am getting the following error.
Access to fetch at 'https://.../upload' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
In my API Gateway I have the following configuration for that method
Gateway Responses for UserUpload API: default 4XX (not checked), default 5XX (not checked)
Methods: post (checked), options (checked)
Access-Control-Allow-Methods: options, post
Access-Control-Allow-Headers: '*'
Access-Control-Allow-Origin: '*'
This API uses an authorizer, I am using the one provided by Auth0 and have not edited the code at all.
And the function that my authorizer calls returns the response like the below (eg happy path):
exports.handler = async (event) => {
//do data checks and upload to s3
return {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Origin": "*",
},
statusCode: 200,
body: JSON.stringify({ message: "success" }),
};
This is my first time setting up both a lambda function, authorisation provider and API Gateway so I might be missing something obvious. I have also tried added mode: no-cors to my fetch POST requests however they still fail in a very similar way.
From what I can tell by looking at the logs of the authorizer and the lambda function that uploads the images, is that they are not even being called. So it appears the CORS error is with the API Gateway.
I have seen in a few tutorials that in their aws template yaml files they add an option AddDefaultAuthorizerToCorsPreflight as False. I can't see this anywhere in the API Gateway console.
Update: I have tested my function with the custom authoriser turned off and it works. So I know that CORS works for the options method, and for the returned request on the lambda function. It is the custom authoriser that is the problem.
The flow is currently:
Method Request - Auth: my-auth-0-authorizer
Integration Request - Type: Lambda_proxy
Lambda function
Integration response - [greyed out Proxy integrations cannot be configured to transform responses]
Method Response: HTTP Status: Proxy (with Access-Control-Allow-Origin in the response headers)
What do I have to do differently or change to allow my authoriser to respect the CORS config?
Update: After leaving my API Gateway for a day, successful responses are now working (using the flow mentioned above). I am not sure if there was a glitch in the system or there was unexpected occurring but it is now working. I am still getting a CORS issue but now only with bad responses.
The custom authoriser fails by return context.fail("Unauthorized"); and when this occurs my browser gets a CORS error. Do I have to set up special gateway responses for 4XX responses?
I'm trying to set up a WebSocket API on API Gateway. I'm following the basic tutorial, and I have everything up and running -> Routes for $connect, $disconnect, "test", $default. I am able to connect to the API, store the connectionId in Redis, and retrieve it when accessing from the test route.
The problem is when I try to send back a message from my lambda (single lambda handling all routes). I'm using the following code
const apigwManagementApi = new AWS.ApiGatewayManagementApi({
apiVersion: '2018-11-29',
endpoint: `https://${event.requestContext.domainName}/${event.requestContext.stage}`
});
Then I call
await apigwManagementApi.postToConnection({
ConnectionId: connectionId,
Data: `Echo: ${data}`
}).promise()
This is only called on the "test" route.
All of this is as per their guide. I had to add a patch to be able to make postConnection work, again, as per their tutorial. The problem is when the above method is called I get a Internal Server Error message from the API Gateway and the lambda times out after 3 seconds.
There is very little info on this method. I'm not sure what is causing the internal server error. I have checked the endpoint and the connectionId, both are correct.
What am I doing wrong? Any suggestions?
So the problem wasn't the actual lambda but the fact that it wasn't set up in a VPC that had access to the Internet. So if you're lambda has VPC enabled, make sure you it has a NAT gateway and Internet gateway set up.
I can't figure out how to return http status codes for functions behind an API GW. No matter what I return, it always comes back as a 200. I've tried statusCode and code to no avail.
I'm using the Serverless framework with the OpenWhisk plugin. I'm deploying to IBM Cloud.
Web Action response content type parameter must be set to http to manually configure the HTTP response. This value defaults to json which ignores returned headers and statusCode values.
In The Serverless Framework, this value is set in the event configuration section of your YAML.
functions:
my_function:
handler: index.main
events:
- http:
method: GET
path: /api/greeting
resp: http