请求内容校验¶

请求数据会由不同的代码来处理或者预处理。例如 JSON 数据和表单数据都来源于已经读取并处理的请求对象,但是它们的处理代码是不同的。这样,当需要校验进来的请求 数据时就会遇到麻烦。因此,有时候就有必要使用一些 API 。

幸运的是可以通过包装输入流来方便地改变这种情况。

下面的例子演示在 WSGI 环境下读取和储存输入数据,得到数据的 SHA1 校验:

  1. import hashlib
  2.  
  3. class ChecksumCalcStream(object):
  4.  
  5. def __init__(self, stream):
  6. self._stream = stream
  7. self._hash = hashlib.sha1()
  8.  
  9. def read(self, bytes):
  10. rv = self._stream.read(bytes)
  11. self._hash.update(rv)
  12. return rv
  13.  
  14. def readline(self, size_hint):
  15. rv = self._stream.readline(size_hint)
  16. self._hash.update(rv)
  17. return rv
  18.  
  19. def generate_checksum(request):
  20. env = request.environ
  21. stream = ChecksumCalcStream(env['wsgi.input'])
  22. env['wsgi.input'] = stream
  23. return stream._hash

要使用上面的类,你只要在请求开始消耗数据之前钩接要计算的流就可以了。(按:小心操作 request.form 或类似东西。例如 before_request_handlers 就应当小心不要操作。)

用法示例:

  1. @app.route('/special-api', methods=['POST'])
    def special_api():
    hash = generate_checksum(request)

  2. # Accessing this parses the input stream
  3. files = request.files
  4. # At this point the hash is fully constructed.
  5. checksum = hash.hexdigest()
  6. return 'Hash was: %s' % checksum

原文: https://dormousehole.readthedocs.io/en/latest/patterns/requestchecksum.html