首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django主体编码与slack-api秘密

Django主体编码与slack-api秘密
EN

Stack Overflow用户
提问于 2019-02-14 09:24:38
回答 1查看 202关注 0票数 0

我正在按照这个page的说明进行操作。我正在构建一个松弛的斜杠命令处理服务器,并且我无法重新构建签名来验证斜杠请求的真实性。

下面是我的django应用程序的代码片段(视图使用django rest-framework APIView):

代码语言:javascript
运行
复制
@property
def x_slack_req_ts(self):
    if self.xsrts is not None:
        return self.xsrts
    self.xsrts = str(self.request.META['HTTP_X_SLACK_REQUEST_TIMESTAMP'])
    return self.xsrts

@property
def x_slack_signature(self):
    if self.xss is not None:
        return self.xss
    self.xss = self.request.META['HTTP_X_SLACK_SIGNATURE']
    return self.xss

@property
def base_message(self):
    if self.bs is not None:
        return self.bs
    self.bs = ':'.join(["v0", self.x_slack_req_ts, self.raw.decode('utf-8')])
    return self.bs

@property
def encoded_secret(self):
    return self.app.signing_secret.encode('utf-8')

@property
def signed(self):
    if self.non_base is not None:
        return self.non_base
    hashed = hmac.new(self.encoded_secret, self.base_message.encode('utf-8'), hashlib.sha256)
    self.non_base = "v0=" + hashed.hexdigest()
    return self.non_base

这是在一个类中,其中self.raw = request.body是django请求,而self.app.signing_secret是一个带有适当松弛秘密字符串的字符串。当self.non_base产生不准确的值时,它不起作用。

现在,如果我打开一个交互式python repl并执行以下操作:

代码语言:javascript
运行
复制
>>> import hmac
>>> import hashlib
>>> secret = "8f742231b10e8888abcd99yyyzzz85a5"
>>> ts = "1531420618"
>>> msg = "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"
>>> ref_signature = "v0=a2114d57b48eac39b9ad189dd8316235a7b4a8d21a10bd27519666489c69b503"
>>> base = ":".join(["v0", ts, msg])
>>> hashed = hmac.new(secret.encode(), base.encode(), hashlib.sha256)
>>> hashed.hexdigest()
>>> 'a2114d57b48eac39b9ad189dd8316235a7b4a8d21a10bd27519666489c69b503'

您将会识别出引用的链接示例。如果我在示例中使用django应用程序中的值,它可以在repl中工作,但不能在django应用程序中工作。

我的问题是:我认为这是由于self.raw.decode()编码与我提取来复制/粘贴到repl中的打印输出不一致造成的。有没有人遇到过这个问题?解决方法是什么?我用urllib.parse库尝试了一些随机的东西……如何确保request.body编码与使用get_data()的flask中的示例一致(如链接中的文档所建议的)?

更新:我定义了一个自定义解析器:

代码语言:javascript
运行
复制
class SlashParser(BaseParser):
"""
Parser for form data.
"""
media_type = 'application/x-www-form-urlencoded'

def parse(self, stream, media_type=None, parser_context=None):
    """
    Parses the incoming bytestream as a URL encoded form,
    and returns the resulting QueryDict.
    """
    parser_context = parser_context or {}
    request = parser_context.get('request')
    raw_data = stream.read()
    data = QueryDict(raw_data, encoding='utf-8')
    setattr(data, 'raw_body', raw_data) # setting a 'body' alike custom attr with raw POST content
    return data

为了在自定义解析器中基于this question和raw_body进行测试,生成与正常“正文”完全相同的散列签名,但同样,将粘贴复制到repl中以在DRF外部进行测试。我很确定这是一个编码问题,但完全不知所措...

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-02-15 03:49:23

我发现这个问题非常令人沮丧。

事实证明,签名密钥存储在太短的字符串数组中,并且缺少尾随字符,这显然会导致消息的散列错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54681902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档