我有一个松弛的应用程序,该应用程序正在发送到用打字稿编写的服务,该服务会将消息转发到我的python脚本中,以尝试验证请求。但是,由于某些原因,验证始终会失败。 打字稿的相关代码:
const rp = require('request-promise');
var qs = require('querystring')
export const handler = async (event: any, context: Context, callback: Callback): Promise<any> => {
const options = {
method: method,
uri: some_url,
body: qs.parse(event.body),
headers: {
signature: event.headers['X-Slack-Signature'],
timestamp: event.headers['X-Slack-Request-Timestamp']
},
json: true
};
return rp(options);
python代码(基于此article):
def authenticate_message(self, request: Request) -> bool:
slack_signing_secret = bytes(SLACK_SIGNING_SECRET, 'utf-8')
slack_signature = request.headers['signature']
slack_timestamp = request.headers['timestamp']
request_body = json.loads(request.body)['payload']
basestring = f"v0:{slack_timestamp}:{request_body}".encode('utf-8')
my_signature = 'v0=' + hmac.new(slack_signing_secret, basestring, hashlib.sha256).hexdigest()
return hmac.compare_digest(my_signature, slack_signature))
我很确定问题是我采取身体的方式,但是尝试了几种选择,但仍然没有运气。
有什么想法吗?
谢谢, 尼尔。
答案 0 :(得分:0)
我遇到了同样的问题。我的解决方案是解析有效负载以将 '/' 替换为 %2F,将 ':' 替换为 %3A。它在 Slack doc 中没有明确显示,但如果您看到示例,它就是这样显示的:
'v0:1531420618:token=xyzz0WbapA4vBCDEFasx0q6G&team_id=T1DC2JH3J&team_domain=testteamnow&channel_id=G8PSS9T3V&channel_name=foobar&user_id=U2CERLKJA&user_name=roadrunner&command=%2Fwebhook-collect&text=&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%2FT1DC2JH3J%2F397700885554%2F96rGlfmibIGlgcZRskXaIFfN&trigger_id=398738663015.47445629121.803a0bc887a14d10d2c447fce8b6703c'
您会看到 command
和 response_url
被解析。
我设法在 Python 中实现了这个功能。我看到你在 Typescript 中提问,但我希望这个 python 脚本有帮助:
@app.route('/slack-validation', methods=['GET', 'POST'])
def slack_secutiry():
headers = request.headers
timestamp = request.headers['X-Slack-Request-Timestamp']
slack_payload = request.form
dict_slack = slack_payload.to_dict()
### This is the key that solved the issue for me, where urllib.parse.quote(val, safe='')] ###
payload= "&".join(['='.join([key, urllib.parse.quote(val, safe='')]) for key, val in dict_slack.items()])
### compose the message:
sig_basestring = 'v0:' + timestamp + ':' + payload
sig_basestring = sig_basestring.encode('utf-8')
### secret
signing_secret = slack_signing_secret.encode('utf-8') # I had an env variable declared with slack_signing_secret
my_signature = 'v0=' + hmac.new(signing_secret, sig_basestring, hashlib.sha256).hexdigest()
print('my signature: ')
print(my_signature)
return '', 200