英文:
Is it possible to use the same domain for API Gateway and Static S3 bucket behind a Cloudfront distribution?
问题
我目前正在AWS中创建一个反馈应用程序。我已经将后端部署在Lambda中,它与API Gateway连接,前端部分由位于Cloudfront分发后面的静态S3存储桶提供服务。
我想在API Gateway上启用TLS 1.2,但似乎只能通过Cloudfront实现。我还想能够在与S3存储桶不同路径但相同域名下提供服务。目前,S3存储桶位于feedback.domain.com。我以前将自定义域名绑定到API Gateway的api.feedback.domain.com上,这在我通过Postman进行请求时有效。但是,当我通过S3存储桶页面上的JavaScript进行请求时,它从不起作用,我会收到CORS错误。如果这是更可行的解决方案,我愿意使用它,但我需要提出有关CORS的另一个问题。
我希望API Gateway位于feedback.domain.com/api,因为据我所知,使用与发出请求的页面相同的域名应该解决CORS问题。我尝试了以下设置,但无法使其正常工作。
当我浏览feedback.domain.com/api时,我看到了我在Cloudfront中设置的错误页面。我尝试创建了一个使Cloudfront分发缓存失效的操作,但这并没有改变任何事情。
我修改了设置,使S3存储桶的源路径为/web/*,但随后到处都会出现AccessDenied错误。
非常感谢提供智慧建议的任何人:)
更新:
以下是我的API阶段的Cloudwatch日志。我访问feedback.domain.com/api时,会收到一个403错误,其中包含我在Cloudfront中定义的自定义错误页面,但在Cloudwatch中没有日志记录:
@Caldazar注意,您提到403意味着我正在访问API,但如果我访问无效的URL,如feedback.domain.com/IDoNotExist,我仍然会收到403错误。我认为这与S3有关?
英文:
I'm currently creating a feedback app in AWS. I have the backend in Lambda which is connected to API Gateway and the frontend of it is served by a Static S3 bucket behind a Cloudfront distribution.
I would like to enable TLS 1.2 on the API Gateway, however, this only seems possible via Cloudfront. I also want to be able to serve it on the same domain name but a different path as the S3 bucket. Currently, the S3 bucket sits on feedback.domain.com. I did have a custom dodmain hooked up to the API Gateway on api.feedback.domain.com, which would work when I made requests to it via Postman. However, when I made requests via the JavaScript on the S3 bucket pages, it would never work and I'd get a CORS error. I am happy to use this if more viable but I would need to ask another question about CORS.
I would like to get the API Gateway to sit on feedback.domain.com/api, because as far as I know, using the same domain as the page making the request should overcome CORS. I've tried the below setup but cannot get this to work.
When I browse to feedback.domain.com/api, I get the error page I set up in Cloudfront. I've tried creating an invalidation so it has cleared the cache on the Cloudfront distribution, but this hasn't changed anything.
I modified the setup so the S3 bucket's origin path was /web/* however i then proceed to get AccessDenied errors everywhere
Setup:
Thank you in advance to anyone that can offer their wise wisdom
UPDATE:
Below are my Cloudwatch Logs for the API stage. I go to feedback.domain.com/api, get a 403 error with my custom error page defined in Cloudfront, but no log in Cloudwatch:
A note to @Caldazar, You mention 403 means I'm hitting the API, however, if I go to a none-valid url, feedback.domain.com/IDoNotExist I still get a 403 error. I believe this is something to do with S3?
答案1
得分: 1
问题出在你的Origin path
上。
实际上,Origin path
的值是在将请求发送到源时将附加到请求的内容。例如,对https://example.com/api/test
的请求将导致发送到https://example.com/api/*/api/test
的请求。
对于API Gateway,你的Origin path
应该是你的API阶段,例如/dev
,/prod
...
你应该创建额外的behavior
,其路径模式应为/api/*
,并且Origin
设置为你上面创建的API origin
。
由于你的路径中有/api/
,这样的路径不会正确匹配到你在API Gateway
中的路径。为了处理这个问题,你应该将一个CloudFront Function
添加到上面创建的API behavior
中,作为Viewer request
的一部分。CloudFront Functions
位于Edit behavior
页面的底部。这个函数应该将/api
更改为/
。以下是我在这种情况下可行的代码:
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI starts with "api"
if (uri.startsWith('/api/')) {
request.uri = uri.replace('/api/', '/');
}
return request;
}
基于新的详细信息进行编辑:
为了访问API,你不能进入/api
。你的行为设置是仅当你的路径为/api/*
时才转发到API Gateway
,这意味着只有当你访问像feedback.domain.com/api/mymethod
这样的URL时才会触发。
至于第二部分,如果文件不存在,S3将返回403代码,因为有可能文件实际上存在,但用户没有权限查看该文件。
英文:
The problem is in your Origin path
.
The Origin path
value is actually what will be appended to your request when it's sent to the origin. For example, a request to https://example.com/api/test
would result in a request being sent to https://example.com/api/*/api/test
For API Gateway, your Origin path
should be your API stage, for example /dev
, /prod
...
You should create additional behavior
that would have Path pattern /api/*
and Origin
set to your API origin
that you created above.
Since you would have /api/
in your path, this wouldn't be matched properly to the path you have in API Gateway
. To deal with that, you should add a CloudFront Function
to your API behavior
created above as part of the Viewer request
. CloudFront Functions
are at the bottom of the Edit behavior
page. This function should change /api
to /
. This is code that works for me for such situations:
function handler(event) {
var request = event.request;
var uri = request.uri;
// Check whether the URI starts with "api"
if (uri.startsWith('/api/')) {
request.uri = uri.replace('/api/', '/');
}
return request;
}
Edit based on new details:
In order to hit the API, you cannot go to /api
. You behaviour is set to forward to API Gateway
only if your path is /api/*
which means, only if you go to a URL like feedback.domain.com/api/mymethod
.
As for the second part, S3 will return 403 code if a file does not exist, because there's a possibility that a file actually exists, but your user does not have permission to see the file.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论