4

我已经通过 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(...).hexdigest() 和 compare_digest() 来自 secrets 包,但收到的签名总是不同。

我做错了什么?

4

2 回答 2

3

我已经更新了代码。现在它运作良好。

于 2020-01-11T16:59:43.020 回答
0

使用 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
于 2022-03-02T09:55:16.197 回答