簡體   English   中英

API網關lamba-proxy集成中的CORS問題

[英]CORS issue in API gateway lamba-proxy integration

我目前在一個無服務器應用程序上,我的 serverless.yml 看起來像

functions:
  app:
    handler: server.run
    events:
     - http:
          path: /api/{any+}
          method: ANY 

     - http:
          path: /secure/api/{any+}
          method: ANY 
          cors :
            origins
              - domain-url-1
              - domain-url-2

正如您在上面看到的,一個是安全路由,需要授權,而非安全路由不需要傳遞任何授權標頭。 由於 lambda-proxy 不接受 api 網關響應,因此我將響應標頭附加到我的 app.js 上,如下所示,對於每條路由,我都在 res 對象中分別發送狀態和狀態代碼。

app.use((req, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "*");
  res.header("Access-Control-Request-Headers", "*");
  // res.headersSent("Access-Control-Allow-Headers", "Content-Type");
  res.header('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept, Authorization, accesstoken");
  res.header('Access-Control-Allow-Credentials', true);
  next();
}); 

但是我的 api 網關適用於非安全路由,而對於安全路由,我遇到了 CORS 問題

** Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
polyfills.ff5fcb5319b1dc651f7b.js:1 GET https://8nv8r4ph65.execute-api.us-east-1.amazonaws.com/staging/secure/api/v1/legal/notification/list?rowsPerPage=15 net::ERR_FAILED **

我不確定我哪里出錯了。

您的源頭與 ApiGateway 中的指定域不匹配。 為了快速驗證,請刪除無服務器中的指定域。

這是因為您的安全路由正在使用其中一種方法來傳遞瀏覽器檢測為帶有憑據的請求的身份驗證狀態。 瀏覽器將請求標記為已認證的一些方法是請求發回 cookie 或請求包含Authorization標頭。

有憑據的請求有一個關於 CORS 的附加規則。 對於有憑據的請求,來源*是非法的。 相反,瀏覽器制造商希望服務器管理員/后端開發人員准確地告訴瀏覽器哪個域名對 CORS 請求有效。

除了上述規則外,域名列表對於憑據請求也是非法的。 帶有憑據的請求只能接受一個域用於 CORS。

您當然可以在服務器代碼中硬編碼前端的域名。 但這會很煩人,並且在您需要為多個域提供服務時不靈活。

此場景的正確工作解決方案(實際上,CORS 的使用方式)是檢查請求中的Origin標頭。

使其工作的最懶惰的方法是簡單地將Origin標頭復制到Access-Control-Allow-Origin

res.header("Access-Control-Allow-Origin", req.get("Origin"));

這將允許世界上任何人從任何網站訪問您的數據。 如果您對此感到滿意並且只關心使用身份驗證來保護您的數據而不是使用 CORS 機制,那么這完全沒問題。

如果您正在使用cors中間件,如果您將true作為原點傳遞,它將為您執行此操作:

app.use(cors({ origin: true }));

CORS 的使用方式是根據已批准的域列表檢查Origin

const approvedDomains = [
    "https://www.google.com",
    "https://my.application.com",
    "http://my.application.com"   // etc..
]

function checkDomains(origin) {
    return approvedDomains.filter(domain => domain === origin)[0];
}

res.header("Access-Control-Allow-Origin", checkDomains(req.get("Origin")));

同樣, cors中間件使這變得簡單,允許您傳遞一組已批准的域名,它將為您執行上述邏輯:

app.use(cors({ origin: approvedDomains });

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM