在Tornado服务器中安全处理Twilio请求,tornadotwilio,Twilio是一种电话服
在Tornado服务器中安全处理Twilio请求,tornadotwilio,Twilio是一种电话服
Twilio是一种电话服务。通过POST一个url和服务器交互,服务器收到请求后可以根据需求来处理电话或者短信。 服务器和Twilio之间的通信机制是非常复杂的。如果你用Nginx做代理,后端使用Tornado的话,下面的代码实现了Http授权:
关于授权部分的代码来自Kevin Kelley,其他部分是我自己写的。
# A decorator that lets you require HTTP basic authentication from visitors.# Kevin Kelley <kelleyk@kelleyk.net> 2011# Use however makes you happy, but if it breaks, you get to keep both pieces.# Post with explanation, commentary, etc.:# http://kelleyk.com/post/7362319243/easy-basic-http-authentication-with-tornadoimport base64, loggingimport tornado.webimport twilio # From https://github.com/twilio/twilio-pythondef require_basic_auth(handler_class): def wrap_execute(handler_execute): def require_basic_auth(handler, kwargs): auth_header = handler.request.headers.get('Authorization') if auth_header is None or not auth_header.startswith('Basic '): handler.set_status(401) handler.set_header('WWW-Authenticate', 'Basic realm=Restricted') handler._transforms = [] handler.finish() return False auth_decoded = base64.decodestring(auth_header[6:]) kwargs['basicauth_user'], kwargs['basicauth_pass'] = auth_decoded.split(':', 2) return True def _execute(self, transforms, *args, **kwargs): if not require_basic_auth(self, kwargs): return False return handler_execute(self, transforms, *args, **kwargs) return _execute handler_class._execute = wrap_execute(handler_class._execute) return handler_classtwilio_account_sid = 'INSERT YOUR ACCOUNT ID HERE'twilio_account_token = 'INSERT YOUR ACCOUNT TOKEN HERE'@require_basic_authclass TwilioRequestHandler(tornado.web.RequestHandler): def post(self, basicauth_user, basicauth_pass): """ Receive a Twilio request, return a TwiML response """ # We check in two ways that it's really Twilio POSTing to this URL: # 1. Check that Twilio is sending the username and password we specified # for it at https://www.twilio.com/user/account/phone-numbers/incoming # 2. Check that Twilio has signed its request with our secret account token username = 'CONFIGURE USERNAME AT TWILIO.COM AND ENTER IT HERE' password = 'CONFIGURE PASSWORD AT TWILIO.COM AND ENTER IT HERE' if basicauth_user != username or basicauth_pass != password: raise tornado.web.HTTPError(401, "Invalid username and password for HTTP basic authentication") # Construct the URL to this handler. # self.request.full_url() doesn't work, because Twilio sort of has a bug: # We tell it to POST to our URL with HTTP Authentication like this: # http://username:password@b-date.me/api/twilio_request_handler # ... and Twilio uses *that* URL, with username and password included, as # part of its signature. # Also, if we're proxied by Nginx, then Nginx handles the HTTPS protocol and # connects to Tornado over HTTP protocol = 'https' if self.request.headers.get('X-Twilio-Ssl') == 'Enabled' else self.request.protocol url = '%s://%s:%s@%s%s' % ( protocol, username, password, self.request.host, self.request.path, ) if not twilio.Utils(twilio_account_sid, twilio_account_token).validateRequest( url, # arguments has lists like { 'key': [ 'value', ... ] }, so flatten them { k: self.request.arguments[k][0] for k in self.request.arguments }, self.request.headers.get('X-Twilio-Signature'), ): logging.error("Invalid Twilio signature to %s: %s" % ( self.request.full_url(), self.request )) raise tornado.web.HTTPError(401, "Invalid Twilio signature") # Do your actual processing of Twilio's POST here, using self.get_argument()
相关内容
- python获得字符的ASCII码,将ASCII数字转换为字符,pytho
- C扩展库中回调Python函数,扩展回调python函数,[C/C++]代码
- python生成格雷码(gray code),pythongray,格雷码(英文:
- Python 处理各种编码的字符串,python编码字符串,Unicode
- 使用decorator检查子类是否实现了父类要求必须实现的方
- python使用rstrip()函数移除行末空白字符,pythonrstrip,pyt
- python从网页中解析网页的字符编码,python字符,[Python]代
- Python使用win32api获取DLL和EXE文件版本号,,[Python]代码i
- python获得随机字符串,python字符串,如下代码生成随机密
- python读写windows注册表,python读写windows,本文封装了_wi
评论关闭