Skip to content

Instantly share code, notes, and snippets.

@dcollien
Last active August 29, 2015 14:26
Show Gist options
  • Save dcollien/0ed0065fb3afc30ecfba to your computer and use it in GitHub Desktop.
Save dcollien/0ed0065fb3afc30ecfba to your computer and use it in GitHub Desktop.
Tornado HMAC Authenticated POST
from tornado import web, ioloop, escape
import hmac, hashlib
SECRET = 'jGW7UPn8T1kpuNP1Op79YIL4Th4a5Cduebgta4riFE2zcAWAmhZToDmevmr4iLfO'
def constant_time_compare(val1, val2):
"""
Returns True if the two strings are equal, False otherwise.
The time taken is independent of the number of characters that match.
"""
if len(val1) != len(val2):
return False
result = 0
for comparisonA, comparisonB in zip(val1, val2):
result |= ord(comparisonA) ^ ord(comparisonB)
return result == 0
def sign(payload):
return hmac.new(str(SECRET), payload, hashlib.sha1).hexdigest()
def is_authentic(signature, body):
return constant_time_compare(signature, sign(body))
class MainHandler(web.RequestHandler):
def prepare(self):
signature = self.request.headers.get('X-Signature', None)
if signature is None or not is_authentic(signature, self.request.body):
raise web.HTTPError(401)
def post(self):
self.write("Authenticated. Woohoo!")
print escape.json_decode(self.request.body)
application = web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8888)
ioloop.IOLoop.current().start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment