无法使用 Rest APIgateway 将参数传递给 AWS Lambda

时间:2021-05-14 15:04:19

标签: python-3.x aws-lambda aws-api-gateway

我在尝试通过 API 网关 rest API 传递一些参数 lambda 函数时遇到问题。请在下面找到代码和错误。

签署请求的代码:

import sys, os, base64, datetime, hashlib, hmac 
import requests 
from pdb import set_trace as bp
method = 'POST'
service = 'execute-api'
host = 'fbyw409pah.execute-api.ap-south-1.amazonaws.com'
region = 'ap-south-1'
endpoint = 'https://fbyw409pah.execute-api.ap-south-1.amazonaws.com/default/Ec2Create'


def sign(key, msg):
    return hmac.new(key, msg.encode('utf-8'), hashlib.sha256).digest()

def getSignatureKey(key, dateStamp, regionName, serviceName):
    kDate = sign(('AWS4' + key).encode('utf-8'), dateStamp)
    kRegion = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'aws4_request')
    return kSigning
try:
    access_key='<access key>'
    secret_key='<secret key>'
except Exception as e:
    pass
if access_key is None or secret_key is None:
    print('No access key is available.')
    sys.exit()

t = datetime.datetime.utcnow()
amzdate = t.strftime('%Y%m%dT%H%M%SZ')
datestamp = t.strftime('%Y%m%d') 

canonical_uri = '/default/Ec2Create' 


canonical_querystring = ''


canonical_headers = 'host:' + host + '\n' + 'x-amz-date:' + amzdate+ '\n'

signed_headers = 'host;x-amz-date'
payload_hash = hashlib.sha256(('').encode('utf-8')).hexdigest()

canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash


algorithm = 'AWS4-HMAC-SHA256'
credential_scope = datestamp + '/' + region + '/' + service + '/' + 'aws4_request'
string_to_sign = algorithm + '\n' +  amzdate + '\n' +  credential_scope + '\n' +  hashlib.sha256(canonical_request.encode('utf-8')).hexdigest()
signing_key = getSignatureKey(secret_key, datestamp, region, service)

signature = hmac.new(signing_key, (string_to_sign).encode('utf-8'), hashlib.sha256).hexdigest()


authorization_header = algorithm + ' ' + 'Credential=' + access_key + '/' + credential_scope + ', ' +  'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature
headers = {'content_type':'application/json','x-amz-date':amzdate, 'Authorization':authorization_header}
request_params = 'AMI=ami-0b84c6433cdbe5c3e&INSTANCE_TYPE=t2.micro&REGION=ap-south-1'
request_url = endpoint + '?' + request_params

print('\nBEGIN REQUEST++++++++++++++++++++++++++++++++++++')
print(request_url)
print(headers)
print(canonical_request)
print(canonical_headers,signed_headers)
r = requests.post(request_url, headers=headers)
print('\nRESPONSE++++++++++++++++++++++++++++++++++++')
print('Response code: %d\n' % r.status_code)
print(r.text)

Lambda:

import json
import boto3
import time
import base64
import datetime
AMI='<ami>'
REGION='ap-south-1'
KEY_NAME = '<mykeypair>'
def myconverter(o):
    if isinstance(o, datetime.datetime):
        return o.__str__()
 
def lambda_handler(event, context):
    INSTANCE_TYPE = event["queryStringParameters"]["INSTANCE_TYPE"]
    ec2 = boto3.client('ec2', region_name=REGION)
    instance = ec2.run_instances(
        ImageId=AMI,
        InstanceType=INSTANCE_TYPE,
        KeyName=KEY_NAME,
        MaxCount=1,
        MinCount=1,
        UserData = userData,
        NetworkInterfaces=[
        {'DeviceIndex': 0,'AssociatePublicIpAddress': True,}]
        
    )
    
    response = ec2.describe_instances(InstanceIds=[instance['Instances'][0]['InstanceId'],])
    # print("\n\t",response)
    print(response['Reservations'][0]['Instances'][0]['State']['Name'])
    while response['Reservations'][0]['Instances'][0]['State']['Name'] =='pending':
        time.sleep(5)
        response = ec2.describe_instances(InstanceIds=[instance['Instances'][0]['InstanceId']])
    print(response)
    return{
        'statusCode':200,
        'body':json.dumps(response,default = myconverter)
        }

错误:

Response code: 403

{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n'POST\n/default/MLOps_EC2_Launch\n3a908c952ca6dfa0e3bb168e74608f22730249f62c1864c91614e41f31548ba0=\nhost:whogwc527k.execute-api.ap-south-1.amazonaws.com\nx-amz-date:20210514T144212Z\n\nhost;x-amz-date\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20210514T144212Z\n20210514/ap-south-1/execute-api/aws4_request\n3d3851f3641eef2f1fc5422f0b87e82f7cf7573375ac6bcb6b3b0348dc8d9a02'\n"}

我可以在不指定任何参数的情况下调用特定的 lambda 函数,但我的工作需要将一些参数附加到 post 请求,以便我可以在 Lambda 函数中指定一些规范。

有人可以告诉我如何将 QueryString 参数添加到请求中吗?

0 个答案:

没有答案