Avoid CORS with AWS Cloudfront, and clean SPA urls
Asked Answered
I

1

5

I have a single-page app that lives in S3, fronted by Cloudfront. There's also a backend that the SPA talks to via AJAX requests. I'm trying to both:

  1. have clean URLs (a la https://keita.blog/2015/11/24/hosting-a-single-page-app-on-s3-with-proper-urls/), by asking cloudfront to rewrite 403 and 404 errors into 200s that produce the index page, and
  2. avoid CORS issues by adding a cloudfront behavior to proxy /api/* to the server (like https://mcmap.net/q/1908124/-how-can-i-use-aws-cloudfront-and-api-gateway-side-by-side-for-the-same-domain).

Is it possible to accomplish both of these? The problem is that cloudfront will change even 403s and 404s that come from the api into 200 index.html responses.

If this can't be done, can you recommend another way to accomplish what I'm trying to do?

Istic answered 13/9, 2018 at 2:48 Comment(0)
I
7

This behavior can be accomplished with Lambda@Edge. Here's the plan:

Create a Lambda function that will be triggered on Origin Request (see diagram for where in the lifecycle that lands). Be sure to create it in us-east-1, as that's the only region where Lambdas to be used in Lambda@Edge can be defined.

Cloudfront possible locations for a Lambda@Edge function

The function has the following job: rewrite requests to paths like /login, /profile, /anything_other_than_assets into /index.html. For me, I was able to make the rule:

Something is an asset if it has an extension. Otherwise, it's a path

Hopefully, you can do the same, or similar. Here's how my function body looked (I used node 8)

const path = require('path')

exports.handler = (evt, ctx, cb) => {
    const {request} = evt.Records[0].cf

    if (!path.extname(request.uri)) {
        request.uri = '/index.html'
    }

    cb(null, request)
}

Make sure you "Publish a new version", and then copy the arn (found at the top of the page)

where to copy the ARN of your new lambda function

paste it in the "Lambda function associations" section of your S3 Origin's Behavior.

Where to paste the ARN of your lambda function

Because Lambda@Edge function associates are scoped to the Origin level, this redirect behavior won't affect your /api/* behavior.

Make sure to remove the custom error handlers. You won't need them anymore for your S3 behavior, and you don't want them for your api behavior.

Istic answered 13/9, 2018 at 3:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.