1
votes

When I use the custom domain https://api-dev.testapp.net:

OPTIONS https://api-dev.testapp.net/dev/locations 403 ()

Failed to load https://api-dev.testapp.net/dev/locations: Response to 
preflight request doesn't pass access control check: No 'Access-Control- 
Allow-Origin' header is present on the requested resource. Origin 
'https://xxxxx0f67xxxxxe7963c04cxxxxx23bf.vfs.cloud9.us-east- 
1.amazonaws.com' is therefore not allowed access. The response had HTTP 
status code 403. If an opaque response serves your needs, set the 
request's mode to 'no-cors' to fetch the resource with CORS disabled.

I have set up an API where each path is a microservice, all pointing back to a custom domain name. Each stage also has a different domain.

I am using cognito for user authentication and as far as I can tell the authentication is functioning properly.

Here is a sample of my serverless.yml

service: testapp-location
plugins:
  - serverless-domain-manager

custom:
  stage: ${opt:stage, self:provider.stage}
  domains:
    prod: api.testapp.net
    test: api-test.testapp.net
    dev: api-dev.testapp.net

customDomain:
  basePath: "locations"
  domainName: ${self:custom.domains.${self:custom.stage}}
  stage: "${self:custom.stage}"
  createRoute53Record: true

package:
  include:
    - models

provider:
  name: aws
  runtime: nodejs6.10
  stage: ${opt:stage, 'dev'}
  environment:
    DATABASE_HOST: ${file(../../config/api/${self:provider.stage}.config.json):DATABASE_HOST}
    DATABASE_NAME: ${file(../../config/api/${self:provider.stage}.config.json):DATABASE_NAME}
    DATABASE_USERNAME: ${file(../../config/api/${self:provider.stage}.config.json):DATABASE_USERNAME}
    DATABASE_PASSWORD: ${file(../../config/api/${self:provider.stage}.config.json):DATABASE_PASSWORD}
  region: us-east-1

I have confirmed that the Route 53 entry has been set-up and pointing to the Cloudfront distribution. The base path mappings are also set-up and the custom domains have valid TLS certs attached to them.

Things should be working, but I think I need a hand debugging this. Any help would be appreciated.

Edit 1: When I use the API Gateway generated url (e.g. OPTIONS https://nnxxxxxe1d.execute-api.us-east-1.amazonaws.com/dev/locations) with no addition headers the request is successful. This makes sense since there is no authorizer on this endpoint and it has a hardcoded 200 response body.

Edit 2: When I run the request (OPTIONS https://api-dev.testapp.net/dev/locations) in Postman I get the following response:

Connection →keep-alive
Content-Length →23
Content-Type →application/json
Date →Thu, 26 Jul 2018 13:40:59 GMT
Via →1.1 b790a9f06b094xxxxxxxxb87e81d4b7f.cloudfront.net (CloudFront)
X-Amz-Cf-Id →3M9kxxxxxxxxlW9Fos_lZqw-lGdPp9MCI7xFIS2-LcXpjGNolsT7jA==
X-Cache →Error from cloudfront
x-amz-apigw-id →Ko1xxxxxxxxF1LA=
x-amzn-ErrorType →ForbiddenException
x-amzn-RequestId →881153c6-90d9-11e8-8d65-738000007497

Which makes me think that the problem is with CloudFront refusing the request.

2

2 Answers

0
votes

What is your Access-Control-Allow-Origin value in your request?. If you don't have it, Add the following to the header of your request:

Access-Control-Allow-Origin: *

I'm suspicious that, because your request goes through multiple access points, the token is not being passed by. Also add domain=whateverdomain.com when you attach the cookie for the authorized user.

0
votes

I had the same problem. The difference in my environment is that I've an extra cloudfront distribution fronting the API gateway (for TLS version enforcement purposes). I received the same errors:

Error: 403 - Forbidden
X-Cache → Error from cloudfront
X-amzn-ErrorType → ForbiddenException

Turns out the API gateway had a custom WAF which didn't have any rules and was denying everything. The fact that I have multiple cloudfront distributions and that the WAF is "hidden" under a regional filter made detection of this quite hard.