在 AWS Lambda 代理(作为使用 Cognito 授权的 API 网关中的集成)中,我想在处理请求时获取用户 ID。Lambda 是使用 Micronaut 用 Java 编写的。同一个 Lambda 被用作多个 API 端点的集成。
我发现 Cognito 用户 ID 包含在提供给 Lambda 处理程序的代理数据的 requestContext 条目中:
public class Handler implements RequestStreamHandler {
private static MicronautLambdaContainerHandler handler = new MicronautLambdaContainerHandler();
@Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
// `input` contains the information I need (see below)
handler.proxyStream(input, output, context);
}
}
当通过 API 调用 Lambda 并作为 Cognito 用户进行身份验证时,input
Steam 看起来像这样(省略了一些细节/更改为示例值,并且 Cognito 用户 ID 被标记为// !!!
):
{
"resource": "/test",
"path": "/test",
"httpMethod": "GET",
"headers": {
"accept": "application/json, text/plain, */*",
"accept-encoding": "gzip, deflate, br",
"accept-language": "en-US,en;q=0.5",
"Authorization": "Bearer eyJraWQiOiJPWlgzYVg3UWNITFwvM09vODg4SzhaYjBlcmRJMjZNNWFRdXF3a3VyZWhaVT0iLCJhbGciOiJSUzI1NiJ9[...]",
"cache-control": "no-cache",
"Host": "api.my-app.example.com",
"origin": "https://my-app.example.com",
"pragma": "no-cache",
"referer": "https://my-app.example.com/home",
"User-Agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0",
"X-Amzn-Trace-Id": "Root=1-5ebbd0f0-[...]",
"X-Forwarded-For": "[...]",
"X-Forwarded-Port": "443",
"X-Forwarded-Proto": "https"
},
"multiValueHeaders": {
/* similar to above but values being arrays */
},
"queryStringParameters": null,
"multiValueQueryStringParameters": null,
"pathParameters": {},
"stageVariables": null,
"requestContext": {
"resourceId": "927cr8",
"authorizer": {
"claims": {
"sub": "c99202cc-e088-43d6-8c15-1fd73a717a7c", // !!!
"cognito:groups": "[...]",
"iss": "https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_[...]",
"cognito:username": "c99202cc-e088-43d6-8c15-1fd73a717a7c", // !!!
"aud": "[...]",
"event_id": "0d509360-d81e-4e7e-b346-9d018ed1cd04",
"token_use": "id",
"custom:[...]": "[...]",
"auth_time": "1587536524",
"name": "[...]",
"exp": "Wed May 13 11:45:53 UTC 2020",
"iat": "Wed May 13 10:45:53 UTC 2020",
"email": "[...]"
}
},
"resourcePath": "/test",
"httpMethod": "GET",
"extendedRequestId": "Md2VmF0OFiAFhZA=",
"requestTime": "13/May/2020:10:50:24 +0000",
"path": "/test",
"accountId": "[...]",
"protocol": "HTTP/1.1",
"stage": "default",
"domainPrefix": "api",
"requestTimeEpoch": 1589367024516,
"requestId": "feb2c8b2-4cf6-405b-bc48-76ebe33fde62",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"sourceIp": "[...]",
"principalOrgId": null,
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0",
"user": null
},
"domainName": "api.my-app.example.com",
"apiId": "[...]"
},
"body": null,
"isBase64Encoded": false
}
然后,MicronautLambdaContainerHandler 在幕后做了很多我还不完全理解的事情;但是,最后我可以在控制器类中使用 micronaut 的注释来定义 API 端点:
@Controller("/")
public class TestController {
@Get("/test")
public HttpResponse<String> test(HttpRequest<?> request) {
String userId = ?
}
}
这个例子是一个请求处理程序GET /test
。
HttpRequest 对象包含原始请求中的所有内容,例如标头和内容,但不包含 AWS 网关添加到其中的信息,例如身份验证的结果。
我现在如何访问它,特别是 requestContext,它是通过其输入传递给 Lambda 的?我在这里遗漏了一些难题。