无法在 AWS Lambda Python 3 (Interactions_Endpoint_URL) 上验证机器人的 Discord 签名

Unable to verify Discord signature for bot on AWS Lambda Python 3 (Interactions_Endpoint_URL)

我正在尝试使用 lambda 函数中的 discord 的“交互端点 URL”验证我的机器人应用程序的签名 运行 python 3.7。使用“安全和授权”部分下的文档 here,我似乎仍然无法在签名上获得有效的 return,每次都会触发异常。我不确定验证的哪个方面不正确。我正在使用 AWS API 网关将 headers 转发到 lambda 函数以便访问它们。如果能为我指明正确的方向,我们将不胜感激。

编辑:

这里是事件在lambda中的输出,供参考。我删除了一些标记为 <> 的安全值。

{'body': {'application_id': '<AppID>', 'id': '<ID>', 'token': '<Token>', 'type': 1, 'user': {'avatar': '4cbeed4cdd11cac74eec2abf31086e59', 'discriminator': '9405', 'id': '340202973932027906', 'public_flags': 0, 'username': '<username>'}, 'version': 1}, 'headers': {'accept': '*/*', 'content-type': 'application/json', 'Host': '<AWS Lambda address>', 'User-Agent': 'Discord-Interactions/1.0 (+https://discord.com)', 'X-Amzn-Trace-Id': 'Root=1-60a570b8-00381f6e26f023df5f9396b1', 'X-Forwarded-For': '<IP>', 'X-Forwarded-Port': '443', 'X-Forwarded-Proto': 'https', 'x-signature-ed25519': 'de8c8e64be2058f40421e9ff8c7941bdabbf501a697ebcf42aa0419858c978e19c5fb745811659b41909c0117fd89430c720cbf1da33c9dcfb217f669c496c00', 'x-signature-timestamp': '1621455032'}}
import json
import os
from nacl.signing import VerifyKey
from nacl.exceptions import BadSignatureError



def lambda_handler(event, context):
    


    # Your public key can be found on your application in the Developer Portal
    PUBLIC_KEY = os.environ['DISCORD_PUBLIC_KEY']
    
    verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY))
    
    signature = event['headers']["x-signature-ed25519"]
    timestamp = event['headers']["x-signature-timestamp"]
    body = event['body']
    
    try:
        verify_key.verify(f'{timestamp}{body}'.encode(), bytes.fromhex(signature))
    except BadSignatureError:
        return (401, 'invalid request signature')

我能够诊断出问题。我无法验证签名,因为 AWS API 网关在到达我的 lambda 函数之前将正文更改为 JSON。这使得签名验证每次都无效。我通过在 API 网关的集成请求部分检查 Lambda 代理集成解决了这个问题。 Lambda Proxy Check Box。这允许将未更改的正文发送到 Lambda,然后我可以验证我的 discord 传出 webhook。下面是我的最终代码。

import json 
import os 
from nacl.signing import VerifyKey 
from nacl.exceptions import BadSignatureError 

def lambda_handler(event, context):

    PUBLIC_KEY = os.environ['DISCORD_PUBLIC_KEY']
    
    verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY))
    
    signature = event['headers']["x-signature-ed25519"] 
    timestamp = event['headers']["x-signature-timestamp"] 
    body = event['body']

    try: 
        verify_key.verify(f'{timestamp}{body}'.encode(), bytes.fromhex(signature))
        body = json.loads(event['body'])
        if body["type"] == 1:
            return {
             'statusCode': 200, 
             'body': json.dumps({'type': 1})
         } 
    except (BadSignatureError) as e:
        return {
             'statusCode': 401, 
             'body': json.dumps("Bad Signature")
         }