繁体   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