Я следую инструкциям на этой странице .Я создаю сервер обработки слабой косой черты и не могу перестроить подпись для проверки подлинности запроса косой черты.
Вот фрагмент кода из моего приложения django (представление использует django rest-framework APIView):
@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 и сделаю следующее:
>>> 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 с одним из моих примеров, он работает в реплее, но не в приложении django.
МОЙ ВОПРОС: Я полагаю, что это вызвано кодом self.raw.decode() кодировка не соответствует распечатке, которую я извлек для копирования / вставки в репле.Кто-нибудь сталкивался с этой проблемой и что за починка?Я попробовал несколько случайных вещей с библиотекой urllib.parse ... Как я могу убедиться, что кодировка request.body согласуется с примером из flask с get_data () (как предложено документом в ссылке)?
ОБНОВЛЕНИЕ: Я определил пользовательский анализатор:
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
Для проверки на основе этот вопрос и raw_body в пользовательском анализаторе генерирует точно такую же хешированную сигнатуру, что и обычный "body ", но опять же, скопируйте вставку в repl для тестирования вне работы DRF.Уверен, что это проблема с кодировкой, но полностью потеряна ...