Ren*_*nan 21 amazon-web-services amazon-cognito aws-lambda
如何获取调用AWS Lambda函数的用户的身份ID(由AWS Cognito登录)?我是否必须在Lambda函数上使用SDK来获取身份标识?
小智 11
在lambda函数里面的AWS javascript SDK中,只需使用context.identity.cognitoIdentityId它对我有用
小智 8
如果您通过API网关,您可以将cognito id(以及用户arn和其他有用信息)传递给Lambda.这解决了我的问题.
如果其他人偶然发现了这一点,我认为这会对您有很大帮助。
请注意,这仅适用于您使用 Cognito 用户池授权器的情况。如果您想将 AWS_IAM 与 Cognito 身份一起使用,请查看我的 github 示例https://github.com/VictorioBerra/js-cognito-auth-example(阅读下面的编辑区域)
如果您选中了“使用 Lambda 代理集成”,那么您将无权访问请求模板映射。但是您可以在 lambda 函数中访问令牌内的声明:
exports.handler = (event, context, callback) => {
//create a response
const response = {
statusCode: 200,
body: JSON.stringify({
"user email": event.requestContext.authorizer.claims.email,
}),
};
callback(null, response);
};
Run Code Online (Sandbox Code Playgroud)
基本上,您需要使用 AWS_IAM 保护您的 APIG,并且您必须通过 Cognito 联合身份进行身份验证,该身份将使用用户池返回 sessionToken示例。这就是使 AWS IAM 凭证成为临时凭证的原因。现在,您拥有了对 APIG 进行身份验证所需的一切。
要对此进行测试,请下载postman的桌面版本,输入您的 API URI(从阶段区域获取),然后在授权下填写 Sig4 签名所需的 5 个字段。您将看到 lambda 函数中的“event.identity”对象加载了该user对象等属性。
如果你想使用APIG自动生成的SDK它配备内置有一个工厂,需要的accessKey,secret以及token和体征一切都是为了你。与 aws-sdk 相同。您可以使用这三个项目初始化凭据,它会自动使用这些临时凭据为您签署所有请求。如果您想直接使用 window.fetch、request、curl 直接手动点击您的 API(在此处插入 http 客户端),您可以计算自己的 Sig4(请注意它可能有点复杂,或者使用现代库为您完成)。
同样作为记录,在进行研究时,我注意到如果您不想使用 AWS_IAM 作为 APIG 授权方,并且您想使用“Cognito Identity Pool Authorizer”,这是 APIG 下拉列表中的一个新选项,您仍然可以获得如果您只是将从成功的 Cognito popl身份验证中获得的 JWT 作为授权标头传递给 APIG ,则 lambda 事件中的大量用户信息。在 JWT 内部有很多属性,您可以在池设置中自定义这些属性。
IMO 专业意见我认为使用 AWS_IAM temp creds 授权器是首选。这样,您可以在 Cognito 身份(Facebook、Twitter、池等)中使用任意数量的不同 IdP。
对于仍在努力在 Lambda 函数中获取 Cognito 用户的 IdentityId 的其他人,经过多个小时的探索,我发现可以通过以下方式在 Lambda 函数中获取 IdentityId,具体取决于您用来调用 Lambda 的方法功能:
IdentityId可以通过以下方式获取:
const IDENTITY_POOL_ID = "us-west-2:7y812k8a-1w26-8dk4-84iw-2kdi849sku72"
const USER_POOL_ID = "cognito-idp.us-west-2.amazonaws.com/us-west-2_an976DxVk"
const { CognitoIdentityClient } = require("@aws-sdk/client-cognito-identity");
const { fromCognitoIdentityPool } = require("@aws-sdk/credential-provider-cognito-identity");
exports.handler = async (event,context) => {
const cognitoidentity = new CognitoIdentityClient({
credentials: fromCognitoIdentityPool({
client: new CognitoIdentityClient(),
identityPoolId: IDENTITY_POOL_ID,
logins: {
[USER_POOL_ID]:event.headers.Authorization
}
}),
});
var credentials = await cognitoidentity.config.credentials()
console.log(credentials)
// {
// identityId: 'us-west-2:d393294b-ff23-43t6-d8s5-59876321457d',
// accessKeyId: 'ALALA2RZ7KTS7STD3VXLM',
// secretAccessKey: '/AldkSdt67saAddb6vddRIrs32adQCAo99XM6',
// sessionToken: 'IQoJb3JpZ2luX2VjEJj//////////...', // sessionToken cut for brevity
// expiration: 2022-07-17T08:58:10.000Z
// }
var identity_ID = credentials.identityId
console.log(identity_ID)
// us-west-2:d393294b-ff23-43t6-d8s5-59876321457d
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods" : "OPTIONS,POST,GET,PUT"
},
body:JSON.stringify(identity_ID)
};
return response;
}
Run Code Online (Sandbox Code Playgroud)
为什么?
使用具有Cognito 用户池授权程序的 API 网关触发器调用 Lambda 函数将导致以下字段(为了简洁起见已删除的其他字段)在event调用中可用:
{
"resource": "/{proxy+}",
"path": "/_",
"httpMethod": "POST",
"headers": {
"Authorization": "eyJrmlaod8(kyC9zdspo0jZIYjRENFlCNVBidnksl89DNm9USDJrT25MSDhjXC9EYkIzMzQ8389iYWxnIjoiUlMyNTYifQ.eyJzdWIiOiI8389yNDg4Ny0wYTRdkiuiOGQtODA4My1kNmIyYzZhYWNhN2YiLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLXdlc3QtMi5hbWF6b25hd3MuY29tXC91cy13ZXN0LTJfZ3dPMjlMckR4IiwiY3VzdG9tOmZpcnN0X2tleSI6ImZhbHNlIiwiY29nbml0bzp1c2VybmFtZSI6IjJjNjI0ODg3LTBhNGItNGE4ZC04MDgzLWQ2YjJjNmFhY2E3ZiIsIm9yaWdpbl9qdGkiOiI0ODEzYzk1Ni01MDM0LTQzNmItYjE5OS00MWZjN2U1ZTQ0ODciLCJhdWQiOiJyNjdwOGdxNnQ5cHJrc2JyYmtxMDVoM2NuIiwiZXZlbnRfaWQiOiJmOWRlNWMxOC0yMTNlLTQ2NDgtOGY4MC1mODdhYWJhNWM4NGUiLCJjdXN0b206YXBpX2tleV9JRCI6Imhoa2hpMmw5cTkiLCJjdXN0b206YXBpX2tleSI6InVzLXdlc3QtMjplOTBkYmUzZC0wN2FhLTRjODQtOGQ0Ny04NjJmZDJhNzQ1MGZfcm5Zalk2YmhaT0lkWXhDcDBDcjNYZWVaYzFuT3ViZnkzdEs5aEtFRFVIZ3FJd1BSTVJuQ2pyWlJYdGNBSVpqWTVnMFFyejN3ek1keGoiLCJ0b2tlbl91c2UiOiJpZCIsImF1dGhfdGltZSI6MTY1ODA0ODg1OSwiZXhwIjoxNjU4MTM2MTk3LCJpYXQiOjE2NTgxMzI1OTcsImp0aSI6IjdmNTdiYWZlLTA1ZGUtNDgwZC1hMDgzLWY1MjlhN2YzNmI2YiIsImVtYWlsIjoidHJldmVuYXc3QGdtYWlsLmNvbSJ9.hk-8ajGP2jO0RQvzwZWp2d5T1BLiWL9q6vvrbXemLBbd2kb1kkBSvklfC_7WWvJoy1ukwNoq8Cx63U2hQfjJB077AHrHfN2PkJu4DG86vSdtSzrZVDQmle331UxopLQvzDZ1mejfmSFbo6x1ZeTbo39PRpox4pzsfeUAM1Rf8H6y8OrdPZa7Gh6gRkiN2IcwdBnXI4-Q6HX5QqiVzr2O4zEnNsqMFfsFA3aO05hnp7EYRWHgS6EgaQjfBirCoyerBkjFJTXynl76Jj4fK3-3KY4tw5EHplxkgAih7a9QTxy8SbRee8kh7fwrIGEO6CtgkM9v0XL7jBPtNtGTpqBRzw"
},
"requestContext": {
"authorizer": {
"claims": {
"sub": "231df9d7-0aab-4dsd-8389-d315d9daca7f",
"email_verified": "true",
"iss": "https://cognito-idp.us-west-2.amazonaws.com/us-west-2_an976DxVk",
"custom:first_key": "false",
"cognito:username": "231df9d7-0aab-4dsd-8389-d315d9daca7f",
"origin_jti": "8131rlpo-5123-436b-b199-41315d9d4487",
"aud": "r6315d9dt9sdls315d9d5h3cn",
"event_id": "f3dsp9d8-213e-4648-8f80-f8315d9dc84e",
"custom:name": "my_name",
"token_use": "id",
"auth_time": "1658148859",
"exp": "Mon Jul 18 09:23:17 UTC 2022",
"iat": "Mon Jul 18 08:23:17 UTC 2022",
"jti": "982sdafe-97rs-996l-i899-k315d9d09n7n",
"email": "jeff@amazon.com"
}
},
"extendedRequestId": "dSiT_dLdJdad9oP=",
"requestTime": "18/Jul/2022:08:23:27 +0000",
"requestTimeEpoch": 1658132607750,
"requestId": "387ss00s3-add0-62i9-l9s0-9a8dj8976dfa",
"identity": {
"cognitoIdentityPoolId": null,
"accountId": null,
"cognitoIdentityId": null,
"caller": null,
"sourceIp": "91.83.769.200",
"principalOrgId": null,
"accessKey": null,
"cognitoAuthenticationType": null,
"cognitoAuthenticationProvider": null,
"userArn": null,
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0",
"user": null
},
"domainName": "mskd8fpni2.execute-api.us-west-2.amazonaws.com",
"apiId": "mskds98ni2"
},
"body": "{\"name\":\"my_name\"}",
"isBase64Encoded": false
}
Run Code Online (Sandbox Code Playgroud)
context并且以下字段在调用中可用:
{
"callbackWaitsForEmptyEventLoop": true,
"functionVersion": "$LATEST",
"functionName": "hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"memoryLimitInMB": "512",
"logGroupName": "/aws/lambda/hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"logStreamName": "2022/07/15/[$LATEST]95edi84719944bdi84a6cdi8451di849",
"invokedFunctionArn": "arn:aws:lambda:us-west-2:598763214571:function:hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"awsRequestId": "d8s57juq-3g39-49sk-8625-5849sk9be44I"
}
Run Code Online (Sandbox Code Playgroud)
请注意以下事项:
event在或contexteventevent(调用 lambda 函数的时间可在event.requestContext.requestTime和中获得event.requestContext.requestTimeEpoch)注意:如果您在为 Lambda 函数使用 Cognito 用户池授权程序设置 API 网关触发器时遇到困难,请发表评论,如果人们感兴趣,我将添加有关如何完成此操作的说明。
IdentityId可以通过以下方式获取:
exports.handler = async (event,context) => {
var identity_ID = context.identity.cognitoIdentityId
console.log(identity_ID)
// us-west-2:d393294b-ff23-43t6-d8s5-59876321457d
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods" : "OPTIONS,POST,GET,PUT"
},
body:JSON.stringify(identity_ID)
};
return response;
}
Run Code Online (Sandbox Code Playgroud)
为什么?
使用适用于 Javascript v3 的 AWS 开发工具包和 Cognito 用户凭证直接调用 Lambda 函数将导致调用中不提供任何其他信息:event
{
"name": "my_name"
}
Run Code Online (Sandbox Code Playgroud)
但是,IdentityId在调用中可用:context
{
"callbackWaitsForEmptyEventLoop": true,
"functionVersion": "$LATEST",
"functionName": "hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"memoryLimitInMB": "512",
"logGroupName": "/aws/lambda/hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"logStreamName": "2022/07/15/[$LATEST]95edi84719944bdi84a6cdi8451di849",
"identity": {
"cognitoIdentityId": "us-west-2:d393294b-ff23-43t6-d8s5-59876321457d",
"cognitoIdentityPoolId": "us-west-2:7y812k8a-1w26-8dk4-84iw-2kdi849sku72"
},
"invokedFunctionArn": "arn:aws:lambda:us-west-2:598763214571:function:hello-world-jsHelloWorldFunction-kTdLswTRrkdS",
"awsRequestId": "d8s57juq-3g39-49sk-8625-5849sk9be44I"
}
Run Code Online (Sandbox Code Playgroud)
请注意以下事项:
context.identity.cognitoIdentityIdeventcontexteventcontext注意:要使用 Cognito 用户的凭证和适用于 JavaScript v3 的 AWS 开发工具包直接调用 Lambda 函数,您需要将自定义 IAM 权限添加到 Cognito 用户池中经过身份验证的用户所承担的 IAM 角色。去做这个:
amplify-myapp-prod-12987-authRole{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"lambda:InvokeFunctionUrl",
"lambda:InvokeFunction"
],
"Resource": [
"arn:aws:lambda:*:598763214571:function:hello-world-jsHelloWorldFunction-kTdLswTRrkdS"
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
根据文档,有关身份提供者的信息似乎只能通过 Mobile SDK 进行调用。
为了解决这个问题,一种选择是将身份 ID 作为事件的一部分手动传递给函数。假设您正在做类似的事情AWS.config.credentials = new AWS.CognitoIdentityCredentials(...),那么您应该能够通过AWS.config.credentials.identityId(刷新凭据后)获取ID。
编辑:身份验证的更好选择是让 Cognito/IAM 处理它,并假设如果用户可以成功调用 Lambda 函数,则意味着他们被允许这样做。在这种情况下,要管理每个用户的验证,请查看白名单。
| 归档时间: |
|
| 查看次数: |
15299 次 |
| 最近记录: |