如何将数据从AWS API Gateway自定义授权者传递到AWS Lambda函数?

时间:2019-05-12 12:22:38

标签: node.js amazon-web-services aws-lambda

我正在使用AWS API GAteway的自定义授权方来验证应用程序的令牌,
我可以与自定义授权人一起正常工作,
即。能够验证令牌并返回IAM策略,
哪个决定是否允许将请求转发到业务逻辑Lambda函数。

我现在需要将其他数据从“自定义授权者”发送到业务逻辑Lambda,

到目前为止,我发现有两种方法可以实现这一目标-
1.将数据字符串化为要返回的策略中的主体ID。
2. Set data in Context object of the policy,根据代码

可以将其检索为$context.authorizer.<key>

我正在尝试第二种方法,但是无法检索在业务逻辑Lambda中在上下文中设置的数据。

我正在使用此GitHub Repo中的NodeJs代码-
https://github.com/awslabs/aws-apigateway-lambda-authorizer-blueprints/blob/master/blueprints/nodejs/index.js

我无法查看设置代码的默认上下文-

authResponse.context = {
    key : 'value', // $context.authorizer.key -> value
    number : 1,
    bool: true
};

以下是业务逻辑Lambda函数中的事件对象日志-

Event: {
    type: 'REQUEST',
    methodArn: 'someARN',
    resource: 'somePath',
    path: 'somePath',
    httpMethod: 'GET',
    headers: {
        accept: '*/*',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'en-US,en;q=0.9',
        authorization: 'someToken',
        'cache-control': 'no-cache',
        'content-type': 'application/json',
        Host: 'someAPI.execute-api.us-east-1.amazonaws.com',
        partner: 'php',
        'postman-token': 'someToken',
        timestamp: '1555034345',
        'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/someIP Safari/537.36',
        'X-Amzn-Trace-Id': 'Root=1-someId',
        'X-Forwarded-For': 'someIP',
        'X-Forwarded-Port': '443',
        'X-Forwarded-Proto': 'https'
    },
    multiValueHeaders: {
        accept: ['*/*'],
        'accept-encoding': ['gzip, deflate, br'],
        'accept-language': ['en-US,en;q=0.9'],
        authorization: ['someToken'],
        'cache-control': ['no-cache'],
        'content-type': ['application/json'],
        Host: ['someAPI.execute-api.us-east-1.amazonaws.com'],
        partner: ['php'],
        'postman-token': ['someToken'],
        timestamp: ['1555034345'],
        'user-agent': ['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/someIP Safari/537.36'],
        'X-Amzn-Trace-Id': ['Root=1-someId'],
        'X-Forwarded-For': ['someIP'],
        'X-Forwarded-Port': ['443'],
        'X-Forwarded-Proto': ['https']
    },
    queryStringParameters: {
        user_id: '4'
    },
    multiValueQueryStringParameters: {
        user_id: ['4']
    },
    pathParameters: {},
    stageVariables: {
        someVariable: 'someValue',
    },
    requestContext: {
        resourceId: 'someId',
        resourcePath: 'somePath',
        httpMethod: 'GET',
        extendedRequestId: 'someId',
        requestTime: '12/May/2019:12:05:51 +0000',
        path: 'somePath',
        accountId: 'someId',
        protocol: 'HTTP/1.1',
        stage: 'dev',
        domainPrefix: 'someAPIDomain',
        requestTimeEpoch: 1557662751493,
        requestId: 'someId',
        identity: {
            cognitoIdentityPoolId: null,
            accountId: null,
            cognitoIdentityId: null,
            caller: null,
            sourceIp: 'someIP',
            principalOrgId: null,
            accessKey: null,
            cognitoAuthenticationType: null,
            cognitoAuthenticationProvider: null,
            userArn: null,
            userAgent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/someIP Safari/537.36',
            user: null
        },
        domainName: 'someAPI.execute-api.us-east-1.amazonaws.com',
        apiId: 'someId'
    }
}

我正在使用默认的Method Request Passthrough-

##  See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
##  This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
#set($allParams = $input.params())
{
"body-json" : $input.json('$'),
"params" : {
#foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
"$type" : {
    #foreach($paramName in $params.keySet())
    "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
        #if($foreach.hasNext),#end
    #end
}
    #if($foreach.hasNext),#end
#end
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
    #if($foreach.hasNext),#end
#end
},
"context" : {
    "account-id" : "$context.identity.accountId",
    "api-id" : "$context.apiId",
    "api-key" : "$context.identity.apiKey",
    "authorizer-principal-id" : "$context.authorizer.principalId",
    "caller" : "$context.identity.caller",
    "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
    "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
    "cognito-identity-id" : "$context.identity.cognitoIdentityId",
    "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
    "http-method" : "$context.httpMethod",
    "stage" : "$context.stage",
    "source-ip" : "$context.identity.sourceIp",
    "user" : "$context.identity.user",
    "user-agent" : "$context.identity.userAgent",
    "user-arn" : "$context.identity.userArn",
    "request-id" : "$context.requestId",
    "resource-id" : "$context.resourceId",
    "resource-path" : "$context.resourcePath"
    }
}

1 个答案:

答案 0 :(得分:0)

能够接收Business Lambda函数上的值,
通过修改API的集成请求下的映射模板-

"context" : {
    .
    .
    .
    myKey : $context.authorizer.key,
    myNum : $context.authorizer.number,
    myBool : $context.authorizer.bool
}

myKey, myNum and myBool的形式在event.context对象下接收到数据。
对于使用API​​网关的集成请求的Lambda代理设置的用户,
不需要任何东西,可以直接传递在Authorizer函数中在上下文上设置的值。
并应收到-

event.requestContext.authorizer