We have a bunch of API endpoints set up in serverless.yml that need to support CORS.
This configuration works:
functions:
function1:
handler: api.refresh
events:
- http:
path: function1
method: post
cors:
origin: '*'
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
But that means we need to duplicate the list of our custom CORS headers for each function - potentially dozens of places we need to update this as soon as we add a new header.
How do we specify the allowed CORS headers once and have them apply to all functions? Ideally we could also automatically make all functions have CORS enabled at the same time.
Currently, serverlessjs does not support to set cors for all function at once, you have to enable cors for each function event.
In the normal way, you just define the cors setting once and apply it for the functions (like a variable)
# ...
custom:
defaultCors:
origin: "*"
headers:
- Content-Type
- X-Amz-Date
- Authorization
- X-Api-Key
- X-Amz-Security-Token
- X-Amz-User-Agent
# ...
functions:
function1:
handler: api.refresh
events:
- http:
path: function1
method: post
cors: ${self:custom.defaultCors}
Related
I have a Gateway configured to handle some services, but there is a huge performance issue and I don't know how can I address this. This is the config for this particular service:
http:
port: 3020
hostname: 'xxxx.prod.xx.xxx.net'
apiEndpoints:
laPrdTest:
host: 'xxx-xxxxxxxx.xxxxxxxx.com'
paths: '/api/v1/esign/*'
serviceEndpoints:
laPrdTest:
urls:
- http://xxxxxx-app1.prd.xxx.xxxxxxxx.net
- http://xxxxxx-app2.prd.xxx.xxxxxxxx.net
policies:
- basic-auth
- cors
- expression
- log
- jwt
- proxy
- rate-limit
pipelines:
laPrdTest:
apiEndpoints:
- laPrdTest
policies:
- cors:
- log:
- action:
message: ${req.method} ${req.originalUrl} ${JSON.stringify(req.headers)}
- rate-limit:
- action:
max: 50
windowMs: 120000
rateLimitBy: "${req.ip}"
- proxy:
- action:
serviceEndpoint: laPrdTest
changeOrigin: true
Check on this gif so you can see how this is very bad on performance:
And this is a call directly to the service API with no performance issue:
Why is this happening?
What can I do to solve this issue?
Finally I couldn't use this anymore an move to do the proxy through Nginx directly.
Any request made through the Gateway it took seconds almost minutes and now using Nginx as a gateway it takes miliseconds.
I followed the following link from swagger documentation to create swagger json for my rest api.
https://swagger.io/docs/specification/2-0/describing-request-body/
In my rest api, I have request body and http headers like Content-Type and Authorization that go along with the service request.
I was wondering if there is a way to include request body and http header information in the swagger json ? I don't see that information in the swagger docs.
The Content-Type header of requests and responses is defined by the consumes and produces keywords, respectively. They can be specified on the operation level or on the root level of the spec.
The Authorization header is defined using the securityDefinitions and security keywords. OpenAPI/Swagger 2.0 supports Basic authentication, API keys and OAuth 2.
Other headers can be defined as in: header parameters.
For example, if an operation POSTs JSON and uses Basic auth, you can describe it as follows:
swagger: '2.0'
...
securityDefinitions: # Authorization, part 1
basicAuth:
type: basic
paths:
/something:
post:
summary: POST some JSON
consumes:
- application/json # Request Content-Type
produces:
- application/json # Response Content-Type
security:
- basicAuth: [] # Authorization, part 2
parameters:
- in: body
name: body
required: true
schema:
$ref: '#/definitions/Something'
responses:
200:
description: OK
Relevant documentation:
MIME Types
Authentication
Describing Parameters
I'd like that the root path of my API redirect (301) to completely another site with docs. So I have a lambda at e.g /function1 path and the / should return code 301 with another location. And I'd like to do it without another lambda.
This is exactly what is described here, but via aws command line tool. I tried this approach - it works perfectly, but I'd like to configure such API gateway mock via serverless framework config.
Fortunately, the series of CLI commands you linked to can be reproduced in CloudFormation, which can then be dropped into the Resources section of your Serverless template.
In this example, a GET to /function1 will invoke a lambda function, while a GET to / will return a 301 to a well-known search engine.
service: sls-301-mock
provider:
name: aws
runtime: nodejs12.x
stage: dev
region: us-east-1
functions:
hello:
handler: handler.hello
events:
- http:
path: function1
method: get
resources:
Resources:
Method:
Type: AWS::ApiGateway::Method
Properties:
HttpMethod: GET
ResourceId:
!GetAtt ApiGatewayRestApi.RootResourceId
RestApiId:
Ref: ApiGatewayRestApi
AuthorizationType: NONE
MethodResponses:
- ResponseModels: {"application/json":"Empty"}
StatusCode: 301
ResponseParameters:
"method.response.header.Location": true
Integration:
Type: MOCK
RequestTemplates:
"application/json": "{\n \"statusCode\": 301\n}"
IntegrationResponses:
- StatusCode: 301
ResponseParameters:
"method.response.header.Location": "'https://google.com'"
Tested with:
Framework Core: 1.62.0
Plugin: 3.3.0
SDK: 2.3.0
Components Core: 1.1.2
Components CLI: 1.4.0
Notes
ApiGatewayRestApi is, by convention, the logical name of the API Gateway Stage resource created by Serverless on account of the http event.
Relevant CloudFormation documentation
ApiGateway::Method
ApiGateway::Method Integration
EDIT
This answer is not as verbose, and uses an http event instead of the Resources section. I haven't tested it, but it may also work for you.
Managed to achieve it with referring one function twice. But see also reply of Mike Patrick - looks more universal
...
events:
- http:
path: main/root/to/the/function
method: get
cors: true
- http:
path: /
method: get
integration: mock
request:
template:
application/json: '{"statusCode": 301}'
response:
template: redirect
headers:
Location: "'my-redirect-url-note-the-quotes-they-are-important'"
statusCodes:
301:
pattern: ''
I am looking for guidance on how to pass the API Gateway context variable (for example: $context.RequestTime) to the proxy lamba.
Basically I want to send the time request has reached in Api gateway to my lambda proxy method as a request header.
Note that I am using serverless framework (serverless.com)
I tried the following but it does not work
events:
- http:
path: /{proxy+}
method: ANY
request:
parameters:
paths:
proxy: true
headers:
requestTime: $context.requestTime
I have Keycloak and Keycloak-Gatekeeper set up in OpenShift and it's acting as a proxy for an application that is running.
The application that Keycloak Gatekeeper is proxying requires a custom cookie to be set so I figured I could use the Gatekeeper's custom header configuration to set this however I'm running into issues.
Configuration looks like:
discovery-url: https://keycloak-url.com/auth/realms/MyRealm
client-id: MyClient
client-secret: MyClientSecret
cookie-access-name: my.token
encryption_key: MY_KEY
listen: :3000
redirection-url: https://gatekeeper-url.com
upstream-url: https://app-url.com
verbose: true
resources:
- uri: /home/*
roles:
- MyClient:general-access
headers:
Set-Cookie: isLoggedIn=true
After re-deploying and running through the auth flow, the upstream URL/application is not receiving the custom header. I tried with multiple headers (key/value) but can't seem to get it working or find where that header is being injected in the flow.
I've also checked logs and haven't been able to find anything super useful.
Sample Gatekeeper Config
Gatekeeper Custom Headers Docs
Any suggestions/ideas on how to get this working?
remove Set-Cookie.
Simply add
headers:
isLoggedIn: true