avatar

SPA 放 AWS Cloudfront 上時,遇到需修正安全性 HTTP Header 怎解?

可能的解法:

  1. Next.js (React) 如果是 Next.js 的話,那恭喜你可以直接在 config 控制 header,這個方法可能是最簡單的,react 如果能在 response 補上 security header 也是可解,其他的框架應該都有類似的解法,相較下面要提的方法,這類解法比較簡單扼要,也不需要額外的花費。
  2. Cloudfront 如果不想兜弄 client 只想找可以直接從 AWS 架構上處理掉的話,本來想說就照它的範例,在 viewer reponse 那段補上 security header 就可以收工了,結果踩到這個坑...

CloudFront does not invoke edge functions for viewer response events when the origin returns HTTP status code 400 or higher.

透過 Cloudfront custom error 的行為是不會觸發 Cloudfront functions & Lambda@Edge 的,但是 SPA 放在 AWS 上面得處理 404 的問題,要導回 index 才能正常運作。

上述的文章的解法就是去攔住是自己實作 404 error,但是這樣得擺在 Origin response 去處理,要用貴貴的 Edge,想說能不能用相對便宜的 Cloudfront functions 處理(如果要處理 Origin request/response 就得用 Edge,這是 Cloudfront functions 跟 Lambda@Edge 最大差別)。

找了一波,發現這個解法,可以用兩個 Cloudfront functions 處理掉。

  1. 如前述,在 viewer response 補上處理需要的 security header 的 Cloudfront functions(下圖的 security-header)。
function handler(event) {
    var response = event.response;
    var headers = response.headers;

    headers['strict-transport-security'] = { value: 'max-age=63072000; includeSubdomains; preload'};
    headers['x-content-type-options'] = { value: 'nosniff'};
    headers['x-frame-options'] = {value: 'DENY'};
    headers['x-xss-protection'] = {value: '1; mode=block'};

    return response;
}
  1. 另一個 Cloudfront functions 放在 viewer request,然後判斷非檔案的請求改導往 index.html(下圖的 spa-request)。
function handler(event) {
    var request = event.request;
    var uri = request.uri;

    if (!uri.includes('.')) {
        request.uri = '/index.html';
    }

    return request;
}

*Cloudfront functions 還有另一個不知道算不算坑的東西,就是它其實不是 Node.js runtime 所以它不能用 Node.js 的內建函式,如果需要撰寫複雜的判斷,可能不是非常順手 🤣

直接在 Cloudfront 下的 behavior 裡面設定即可

cloudfront setting

Reference

powered by WebMention.io

You can skeet this post or discuss it on BlueSky, the comments will show up here.
0Likes0Replies0Mentions

Be the first one to share this article!