【问题标题】:Unable to correctly verify Slack requests无法正确验证 Slack 请求
【发布时间】:2022-01-13 05:04:23
【问题描述】:

我正在使用事件 API 构建一个 Slack 机器人作为工作实验。我目前在验证请求时遇到问题,我不确定自己做错了什么。

机器人是使用 Typescript/Node/AWS Lambda/API Gateway 实现的。我用来验证的代码如下所示

import * as crypto from 'crypto';

export const validateSlackRequest = (
  requestSignature: string,
  signingSecret: string,
  timestamp: string,
  body: string, 
) => {
    
  const baseString = `v0:${timestamp}:${body}`;
  const signature = 'v0=' + crypto.createHmac('sha256', signingSecret)
                                  .update(baseString).digest('hex');

  if (!crypto.timingSafeEqual(Buffer.from(requestSignature, 'utf8'), Buffer.from(signature, 'utf8'))) {
    throw new Error('Slack request verification failed');
  }
};

其中body 只是传递给lambda 的event.body 属性,逐字逐句。目前,当我使用 Slack 教程 here 中的数据时,我围绕这个 pass 编写的单元测试,但是当我在本地替换来自真实请求的数据时失败。

我一直在使用this tutorial 来构建我的代码。令我困惑的是,该教程似乎建议我应该将正文转换为查询字符串格式,然后再将其用作我的基本字符串,尽管 Slack 文档对此只字未提,并说“在反序列化之前使用原始请求正文来自 JSON 或其他形式。”。

【问题讨论】:

  • 你使用的是http body还是slack event body?
  • 我正在使用原始请求正文

标签: node.js typescript amazon-web-services slack


【解决方案1】:

这是一个如何验证 Slack 请求的工作示例,它还支持斜杠命令:

Slack bot event example                                                                                 Run in Fusebit
  import crypto from 'crypto';
  import formurlencoded from 'form-urlencoded';

  export const validateSlackRequest = (
    requestSignature: string,
    timestampHeader: string, // Get it from the request header x-slack-request-timestamp
    contentType: string, // Get it from the request header content-type
    signingSecret: string,
    timestamp: string,
    body: string,
  ) => {
      
    let rawBody;
    if (contentType?.toLocaleLowerCase() === 'application/x-www-form-urlencoded') {
      // Slash commands are sent in this content type
      rawBody = formurlencoded(body);
    } else {
      rawBody = JSON.stringify(body)
        .replace(/\//g, '\\/')
        .replace(/[\u007f-\uffff]/g, (c) => '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4));
    }

    const basestring = ['v0', timestampHeader, rawBody].join(':');
    const calculatedSignature = 'v0=' + crypto.createHmac('sha256', signingSecret).update(basestring).digest('hex');
    const calculatedSignatureBuffer = Buffer.from(calculatedSignature, 'utf8');
    const requestSignatureBuffer = Buffer.from(requestSignature, 'utf8');
    return crypto.timingSafeEqual(calculatedSignatureBuffer, requestSignatureBuffer);
  };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 2020-09-16
    • 2018-12-18
    • 1970-01-01
    • 2021-08-11
    • 1970-01-01
    • 2021-06-15
    相关资源
    最近更新 更多