簡體   English   中英

當使用 http 從 JS 獲取請求到 SlackAPI 時,Access-Control-Allow-Headers 在飛行前響應中不允許請求 header 字段授權

[英]Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response when using http get req from JS to SlackAPI

我知道有很多類似的問題,但我發布這個是因為我覺得它略有不同。

我正在嘗試使用 HTTP 請求向 Slack API 發送 GET 請求。 具體來說,代碼如下所示。

import useSWR from "swr";

const useSlackSearch = (query: string) => {
  const token = process.env.NEXT_PUBLIC_SLACK_API_USER_TOKEN;
  const myHeaders = new Headers();
  myHeaders.append("Authorization", "Bearer " + token);

  const slackURL = `https://slack.com/api/search.messages?query=${query}`;

  const fetcher = async (url: string) => {
    const response = await fetch(url, {
      headers: myHeaders,
    }).then((res) => res.json());
    return response;
  };

  const { data, error } = useSWR(slackURL, fetcher, {
    revalidateOnFocus: true,
    revalidateOnReconnect: true,
  });

  if (error) {
    return console.log(`Failed to load: ${error}`);
  } else if (!data) {
    return console.log("Loading...");
  } else {
    console.log(data);
    return data;
  }
};

export default useSlackSearch;

我使用的環境如下。

閱讀下面的 MDN 文章后,我明白了

  • MDN 定義了一個簡單的 HTTP 請求
  • 如果你要發送的請求與這個簡單的請求不對應,瀏覽器會發送一個預檢請求
  • 在對該預檢請求的響應中,有一個名為 Access-Control-Allow-Headers 的 header。
  • 只有設置為此 Access-Control-Allow-Headers header 值的標頭才能在預檢后用作主請求中的標頭。
  • 在這種情況下,我嘗試使用Authorization header,但被上述限制所困。

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

這就是我的全部理解。 但是,在相關方法的官方 Slack API 頁面上,它說要在授權 header 中指定令牌,所以我遇到了麻煩。

我也不明白如何在預檢 header 中指定 Access-Control-Request-Headers,如另一個提問者的主題中所述。 原因是在這種情況下,唯一與 Slack API 通信的是瀏覽器,唯一相關的來源是 JavaScript(准確地說是 React / Next.js)!


之后,我發現來自 Slack API 的預檢響應如下;

access-control-allow-headers: slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, x-b3-sampled, x-b3-flags

正如我所想,我知道授權是不允許的,因為它沒有作為一個值包含在內。 所以問題是如何解決它。

在此處輸入圖像描述


此外,我后來發現來自瀏覽器的預檢請求正確聲明它想使用授權作為實際請求 header。但是,預檢響應不包含該值。

在此處輸入圖像描述

按照 CBroe 的建議,我可以直接聯系 Slack 幫助中心,所以我問了這個問題。 結果我發現,截至 2022 年 2 月,來自瀏覽器的 HTTP 請求不受支持。當然,他們收到了很多關於此的請求,因此他們希望在某個時候解決它。

這一次,瀏覽器在預檢請求中發送了 Access-Control-Request-Headers:Authorization。 但是 Slack API 服務器端不允許來自瀏覽器的請求中的 Authorization header。 因此,未在 Slack API 端的預檢響應中的 Access-Control-Allow-Headers 中設置授權。

結果,來自 Slack API 端的響應返回了 Invalid Auth,即使在從瀏覽器發出實際請求時將 Authorization 添加為 header。

通過這個錯誤,我對CORS和preflighting等HTTP請求有了更深入的了解,但是由於在Slack官網上沒有明確寫,所以我就留在這里了。

我也無法獲得授權 header 工作。 但是,在棄用查詢參數方法之后,Slack 提供了這個示例,用於將令牌身份驗證添加到 Post 正文。 這對我有用,使 Web API 從瀏覽器調用 Slack(用於測試),以便 Slack 讀取令牌進行身份驗證。 請注意,根據 Slack 的安全性最佳實踐,用戶和機器人令牌應小心存儲,不要在客戶端 Javascript 中使用:


    try {
      const res = await fetch("https://slack.com/api/conversations.list", {
        method: "POST",
        body: `token=${TOKEN}`, // body data type must match "Content-Type" header
        headers: {
          "Content-Type": "application/x-www-form-urlencoded",
        },
      }).catch((error) => {
        console.log(error);
      });
      if (!res.ok) {
        throw new Error(`Server error ${res.status}`);
      } else {
        const data = await res.json();
        console.log(data);
      }
    } catch (error) {
      console.log(error);
    }

在請求正文中使用token而不是Authorization header 對我有用。

axios({
  method: 'post',
  url: 'https://slack.com/api/chat.postMessage',
  data: `text=Hi&channel=D048GGYTJUK&token=${process.env.TOKEN}`
})

暫無
暫無

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

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