我正在尝试使用 Slack 文档此处中提供的示例代码来验证我的 Slack 机器人。但是,它返回两个不同的签名。
def lambda_handler(event, context):
# get slack secret from secrets manager
secret = get_secret()
# needed for creating hmac
qstring = base64.b64decode(event['body']).decode('utf-8')
return validate_request(secret, qstring, event['headers'])
# get slack secret for verification from secrets manager
def get_secret():
secret_name = "<omitted>"
region_name = "<omitted>"
session = boto3.session.Session()
client = session.client(
service_name='secretsmanager',
region_name=region_name
)
try:
get_secret_value_response = client.get_secret_value(
SecretId=secret_name
)
except ClientError as e:
if e.response['Error']['Code'] == 'DecryptionFailureException':
raise e
elif e.response['Error']['Code'] == 'InternalServiceErrorException':
raise e
elif e.response['Error']['Code'] == 'InvalidParameterException':
raise e
elif e.response['Error']['Code'] == 'InvalidRequestException':
raise e
elif e.response['Error']['Code'] == 'ResourceNotFoundException':
raise e
else:
if 'SecretString' in get_secret_value_response:
return get_secret_value_response['SecretString']
else:
return base64.b64decode(get_secret_value_response['SecretBinary'])
# validate bot request
def validate_request(secret, body, headers):
timestamp = headers['x-slack-request-timestamp']
sig_basestring = 'v0:' + timestamp + ':' + body
my_signature = 'v0=' + hmac.new(secret.encode('utf_8'), sig_basestring.encode('utf_8'), hashlib.sha256).hexdigest()
slack_signature = headers['x-slack-signature']
if hmac.compare_digest(my_signature, slack_signature):
return True
else:
return False
结果:
v0=24dde133843073b58084970afe027e3a4dabc1b8d9efc5248a97ad64c6529cee
v0=bf51d6fb9eb56d5c6ea19e866b798903fb0cee67264cb467ee7924bb13571770
有什么想法吗?我已经验证
get_secret()
返回了正确的令牌,并且 qstring
变量包含正确的查询参数,如 Slack 文档中所示。标题也都包含正确的值。
对我来说,签名是不同的,因为我将从 slack 请求接收到的正文格式化为 json,然后再传递给验证函数。
通过身体,因为它解决了我的问题。
验证函数要传递的正文格式-
'body': 'token=XXXXXXXXXX&team_id=XXXXXXX&team_domain=XXXXXX&channel_id=XXXXX&channel_name=XXXXXX&user_id=XXX&user_name=XXXX&command=XXXXX&text=XXXX&api_app_id=XXXXXX&is_enterprise_install=false&response_url=XXXXX&trigger_id=XXXXXX'
对于其他仍然陷入困境的人。就我而言,我使用的是邮寄中发送的正文。这是一个 base64 编码的字符串。在签名中使用之前必须对其进行解码。
就我而言,这就是它的作用(
event
因为我将其发送给 lamda):
import base64
body = base64.b64decode(encoded_body).decode('utf-8')
timestamp = post['headers']['X-Slack-Request-Timestamp']
concat_message = ('v0:' + timestamp + ':' + body).encode()
key = 'YOUR-SLACK-SERCRET'.encode()
hashed_msg = 'v0=' + hmac.new(key, concat_message, hashlib.sha256).hexdigest()
slack_signature = post['headers']['X-Slack-Signature']
if (hashed_msg != slack_signature):
return{
'statusCode': 403,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps('Forbidden')
}