有一段时间,我只是将我的网站内容存储在一个s3存储桶中,并且可以通过完整的URL访问所有页面。我想通过添加SSL使我的网站更安全,所以我创建了一个CloudFront Distribution以指向我的s3存储桶。
该网站将加载正常,但如果用户尝试刷新页面或他们尝试使用完整网址(即www.example.com/home)访问网页,他们将收到AccessDenied页面。
我的s3存储桶上有一个策略,它限制只访问Origin Access Identity,并将index.html设置为我的域根对象。
我不明白我错过了什么。
要进行演示,请随时访问我的site。
您会注意到它如何将您重定向到kurtking.me/home。要重现错误,请尝试刷新页面或通过完整URL访问页面(即kurtking.me/life)
我非常感谢任何帮助,因为我一直试图绕过这一点并在几天内寻找答案。
答案 0 :(得分:37)
我已经弄明白了,想要发布我的解决方案以防其他人遇到这个问题。
问题是由于Angular是SPA(单页应用程序)而我使用S3存储桶来存储它。当您尝试通过URL访问转到特定页面时,CloudFront将采用(例如,/ about)并转到您的S3存储桶以查找该文件。因为Angular是SPA,所以在S3存储桶中技术上不存在该文件。这就是我收到错误的原因。
我需要做些什么才能解决问题
如果您在Cloudfront中打开发行版,则会看到“错误页面”标签。我不得不添加两个处理400和403的“自定义错误响应”。400和403的细节相同,所以我只包含400张照片。见下文:
基本上,正在发生的事情是您告诉Cloudfront无论400或403错误,都要重定向回index.html,从而控制Angular来决定它是否可以转到路径。如果您想为客户端提供400或403错误,则需要在Angular中定义这些路由。
设置了两个自定义错误响应后,我部署了我的cloudfront解决方案和wallah,它运行良好!
我使用以下article来指导我解决此问题。
答案 1 :(得分:1)
可接受的答案似乎有效,但这似乎不是一个好习惯。相反,请检查cloudfront来源是否设置为 S3存储桶(其中包含静态文件)或实际的s3 URL端点。它应该是s3 url端点,而不是s3存储桶。
端点之后的网址应为来源
答案 2 :(得分:0)
解决此问题的更好方法是允许列表存储桶权限,并为Cloudfront添加404错误自定义规则以指向index.html。 WAF还会返回403错误,如果将它们添加到index.html进行自定义错误处理,则会导致其他安全问题。因此,最好避免在角度应用程序中首先从S3收到403错误。
答案 3 :(得分:0)
如果您在使用CDK时遇到此问题,则需要添加此内容:
MyAmplifyApp.addCustomRule({
source: '</^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>',
target: '/index.html',
status: amplify.RedirectStatus.REWRITE
});