我已经通过 Github webhooks 实现了在服务器上自动部署我的 Flask 应用程序,但我无法将手册中指定的 Ruby 脚本改编为 Python 3 以验证 POST 请求。我试过这个:
from flask import Flask, request
from hmac import HMAC, compare_digest
from hashlib import sha1
app = Flask(__name__)
def verify_signature(req):
received_sign = req.headers.get('X-Hub-Signature').split('sha1=')[-1].strip()
secret = 'my_secret_string'.encode()
expected_sign = HMAC(key=secret, msg=req.data, digestmod=sha1).hexdigest()
return compare_digest(received_sign, expected_sign)
@app.route('/webhook', methods=['POST', 'GET'])
def webhook():
if request.method == 'POST':
if verify_signature(request):
do_smth()
return 'Successfully', 200
return 'Forbidden', 403
return 'Not allowed', 405
我也尝试了 sha1(...来自secrets软件包的hexdigest((和compare_digest((,但收到的签名总是不同的。
我做错了什么?
使用 SHA-256 而不是 SHA-1
GitHub 建议使用更安全的 SHA-256 代替 SHA-1。
为方便起见,分别更改了您的代码。
from flask import Flask, request
from hmac import HMAC, compare_digest
from hashlib import sha256
app = Flask(__name__)
def verify_signature(req):
received_sign = req.headers.get('X-Hub-Signature-256').split('sha256=')[-1].strip()
secret = 'my_secret_string'.encode()
expected_sign = HMAC(key=secret, msg=req.data, digestmod=sha256).hexdigest()
return compare_digest(received_sign, expected_sign)
@app.route('/webhook', methods=['POST', 'GET'])
def webhook():
if request.method == 'POST':
if verify_signature(request):
do_smth()
return 'Successfully', 200
return 'Forbidden', 403
return 'Not allowed', 405
我已经更新了代码。现在它运行良好。