英文:
How can I validate payloads from GitHub webhooks in Python 3?
问题
我已经实现了通过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
我还尝试了其他使用secrets包中的sha1(...)和compare_digest()的变体,但接收的签名总是不一致。
我做错了什么?
英文:
I've realized auto-deploying of my Flask app on the server by Github webhooks, but I cannot adapt Ruby script specified in the manual to Python 3 to validate the POST-request. I've tried this:
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
Also I tried other variants with sha1(...).hexdigest() and compare_digest() from secrets package, but received signature always differs.
What do I do wrong?
答案1
得分: 3
使用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 '成功', 200
return '禁止访问', 403
return '不允许访问', 405
英文:
Use SHA-256 instead of SHA-1
Instead of SHA-1 GitHub recommends using the more secure SHA-256.
Changed your code respectively for convenience.
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
答案2
得分: 2
我已经更新了代码。现在它运行正常。
英文:
I've updated the code. Now it works well.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论