next.js 使用从JS到SlackAPI的http get req时,预检响应中的Access-Control-Allow-Headers不允许请求标头字段授权

waxmsbnn  于 2023-01-08  发布在  其他
关注(0)|答案(3)|浏览(241)

我知道有很多类似的问题,但我发布这个是因为我觉得它略有不同。
我尝试使用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的标题。
  • 只有设置为此Access-Control-Allow-Headers标头值的标头才能在印前检查后用作主请求中的标头。
  • 在本例中,我尝试使用Authorization头,但它被上述限制所限制。

https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#simple_requests https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
这就是我所理解的全部。然而,在这个方法的官方SlackAPI页面上,它说要在授权头中指定令牌,所以我遇到了麻烦。
我也不明白如何在preflight头文件中指定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

正如我所想,我理解了授权是不允许的,因为它没有作为一个值包含在内。所以问题是如何解决它。

此外,我后来发现来自浏览器的预检请求正确地声明它希望使用Authorization作为实际的请求头,但是预检响应并不包含该值。

8e2ybdfx

8e2ybdfx1#

根据CBroe的建议,我能够直接联系Slack帮助中心,所以我问了这个问题。**结果我发现,从2022年2月底起,浏览器的HTTP请求不受支持。**当然,他们已经收到了相当多关于这个问题的请求,所以他们希望在某个时候解决这个问题。
这一次,浏览器在预检请求中发送了Access-Control-Request-Headers:Authorization。但Slack API服务器端不允许来自浏览器的请求中包含Authorization标头。因此,未在来自Slack API端的预检响应中的Access-Control-Allow-Headers中设置Authorization。
结果,来自Slack API端的响应返回Invalid Auth,即使在从浏览器发出实际请求时Authorization已作为头文件添加。
通过这个错误,我对CORS和preflighting等HTTP请求有了更深入的了解,但由于Slack官方网站上没有明确写出来,所以我就留在这里了。

bfnvny8b

bfnvny8b2#

我也无法使Authorization头工作。但是,Slack提供了这个示例,用于在弃用query parameters方法之后向Post主体添加令牌身份验证。这对我从浏览器进行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);
    }
gcmastyq

gcmastyq3#

在请求主体中使用token而不是Authorization报头对我来说是有效的。

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

相关问题