You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Slack WebClient经代理仍无法跳过证书验证问题求助

问题

在Web服务的TypeScript REST接口中,我需要创建通过mitmproxy代理访问Slack API的Slack WebClient。代码里已经给代理Agent设置了rejectUnauthorized: false来跳过证书验证,但还是出现证书验证失败的错误。客户端日志显示“unable to verify the first certificate”,mitmproxy日志提示客户端不信任代理证书。HTTPS_PROXY环境变量设为https://localhost:8080(mitmproxy监听地址)。全局设置NODE_TLS_REJECT_UNAUTHORIZED=0能解决问题,但这是不良实践,请问如何在通过代理访问时局部跳过Slack的证书验证?

现有代码

private createProxyAwareSlackClient(token: any) {
    const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
    const slackClientOptions = { logLevel: LogLevel.DEBUG };

    if (proxyUrl) {
      slackClientOptions['agent'] =
        new URL(proxyUrl).protocol === 'http' ? new HttpProxyAgent(proxyUrl, {rejectUnauthorized: false}) : new HttpsProxyAgent(proxyUrl, {rejectUnauthorized: false});
    }

    return new WebClient(token, slackClientOptions);
  }

  async firstHandshake(settings: any) {
    const slackWebClient = this.createProxyAwareSlackClient(undefined);
    let response: WebAPICallResult;
    try {
      response = await slackWebClient.oauth.v2.access({
        client_id: process.env.SLACK_CLIENT_ID,
        client_secret: process.env.SLACK_CLIENT_SECRET,
        code: settings.slack_code,
        redirect_uri: settings.redirect_uri
      });
    } catch (e) {
      logger.error(e);
      throw createError(500, 'Cannot get slack api key');
    }

客户端错误日志

[WARN]  web-api:WebClient:8 http request failed unable to verify the first certificate
[DEBUG]  web-api:WebClient:8 http request url: https://slack.com/api/oauth.v2.access
[DEBUG]  web-api:WebClient:8 http request body: {"client_id":"id","client_secret":"secret","code":"some_code","redirect_uri":"some_url"}
[DEBUG]  web-api:WebClient:8 http request headers: {}
[WARN]  web-api:WebClient:8 http request failed unable to verify the first certificate

mitmproxy日志

[23:02:09.731][127.0.0.1:59940] client connect
[23:02:09.826][127.0.0.1:59940] server connect slack.com:443 (some_ip:443)
[23:02:09.911][127.0.0.1:59940] Client TLS handshake failed. The client disconnected during the handshake. If this happens consistently for slack.com, this may indicate that the client does not trust the proxy's certificate.
[23:02:09.913][127.0.0.1:59940] client disconnect
[23:02:09.914][127.0.0.1:59940] server disconnect slack.com:443 (some_ip:443)
解决方案

问题核心:你给代理Agent设置的rejectUnauthorized只控制客户端到代理的TLS验证,但Slack WebClient在处理代理返回的Slack服务证书时,还会走自身的TLS验证逻辑,这部分没被跳过。下面是几种局部解决的方法:

方法1:给Slack WebClient添加专属TLS配置

直接在Slack客户端的选项里添加tls字段,设置rejectUnauthorized: false,这个配置只会作用于当前WebClient实例,不会影响全局:

private createProxyAwareSlackClient(token: any) {
    const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
    const slackClientOptions = { 
      logLevel: LogLevel.DEBUG,
      // 仅当前Slack客户端生效的TLS配置
      tls: { rejectUnauthorized: false }
    };

    if (proxyUrl) {
      slackClientOptions['agent'] =
        new URL(proxyUrl).protocol === 'http' 
          ? new HttpProxyAgent(proxyUrl, {rejectUnauthorized: false}) 
          : new HttpsProxyAgent(proxyUrl, {rejectUnauthorized: false});
    }

    return new WebClient(token, slackClientOptions);
  }

方法2:确保代理Agent的配置覆盖全链路验证

部分情况下,Slack WebClient会优先使用Agent的配置而不是自身的tls选项,此时可以统一给Agent传递验证配置:

private createProxyAwareSlackClient(token: any) {
    const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
    const slackClientOptions = { logLevel: LogLevel.DEBUG };

    if (proxyUrl) {
      const agentOptions = {
        rejectUnauthorized: false
      };
      
      slackClientOptions['agent'] =
        new URL(proxyUrl).protocol === 'http' 
          ? new HttpProxyAgent(proxyUrl, agentOptions) 
          : new HttpsProxyAgent(proxyUrl, agentOptions);
    }

    return new WebClient(token, slackClientOptions);
  }

更安全的替代方案(推荐)

跳过证书验证存在安全风险,更稳妥的方式是将mitmproxy的CA证书加入信任列表,仅让当前Slack客户端信任该证书:

import * as fs from 'fs';

private createProxyAwareSlackClient(token: any) {
    const proxyUrl = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
    // 替换为你的mitmproxy CA证书路径
    const mitmCaCert = fs.readFileSync('./mitmproxy-ca.pem');
    const slackClientOptions = { 
      logLevel: LogLevel.DEBUG,
      tls: { ca: mitmCaCert }
    };

    if (proxyUrl) {
      slackClientOptions['agent'] =
        new URL(proxyUrl).protocol === 'http' 
          ? new HttpProxyAgent(proxyUrl) 
          : new HttpsProxyAgent(proxyUrl, { ca: mitmCaCert });
    }

    return new WebClient(token, slackClientOptions);
  }

内容的提问来源于stack exchange,提问作者rokpoto.com

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 22:49:54