Amazon web services AWS Lambda验证移动应用程序发送的用户令牌?

Amazon web services AWS Lambda验证移动应用程序发送的用户令牌?,amazon-web-services,aws-lambda,amazon-cognito,Amazon Web Services,Aws Lambda,Amazon Cognito,我正在使用Amazon Mobile Hub构建一个移动应用程序。我在MobileHub中使用AWS Cognito对注册和登录的用户进行身份验证。我现在正尝试使用AWS Lambda与DynamoDB进行通信,以执行一些操作 在这样做的时候,我偶然发现了一个问题,那就是我不知道如何验证用户。在某种意义上,如果我通过云逻辑将访问令牌发送到Lambda函数,我将如何验证该令牌并使用从该令牌检索的用户名继续操作 这个SDK允许Lambda函数与AWS Cognito特性通信,但我没有找到任何有用的函

我正在使用Amazon Mobile Hub构建一个移动应用程序。我在MobileHub中使用AWS Cognito对注册和登录的用户进行身份验证。我现在正尝试使用AWS Lambda与DynamoDB进行通信,以执行一些操作

在这样做的时候,我偶然发现了一个问题,那就是我不知道如何验证用户。在某种意义上,如果我通过云逻辑将访问令牌发送到Lambda函数,我将如何验证该令牌并使用从该令牌检索的用户名继续操作

这个SDK允许Lambda函数与AWS Cognito特性通信,但我没有找到任何有用的函数来实际验证令牌

您可以在AWS apigateway中使用对API请求进行授权。 对于所有经过身份验证的API,访问令牌可以作为请求发送,当它到达API网关时,自定义授权器逻辑将被调用,因此将调用lambda函数并验证该访问令牌。
这是定制授权者的权限。

因此,在使用Cognito进行授权时,您有两个选项

1) 您可以将Cognito授权器附加到API上,这“只起作用”,Cognito将验证令牌。您对授权过程没有太多控制权,基本上要么是肯定的,要么是否定的

2) 正如prateek所说,您可以使用自定义授权程序,有点像这样,注意:我将密钥放入了代码中,这是一个非常糟糕的主意,您应该将其存储在环境变量KMS encrypted中

import jwt from 'jsonwebtoken'

export default (event, context, callback) => {

    const key = '' // <--- YOU GET THIS KEY FROM https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json.
    jwt.verify(event.authorizationToken, key, (err, decoded) => {
        if (err) {
            console.log('JWT VALIDATION ERROR')
            callback(null, responder.unAuthorised())
            return
        }

        const principalId = decoded.user.username

        const apiOptions = {}
        const tmp = event.methodArn.split(':')
        const apiGatewayArnTmp = tmp[5].split('/')
        const awsAccountId = tmp[4]
        apiOptions.region = tmp[3]
        apiOptions.restApiId = apiGatewayArnTmp[0]
        apiOptions.stage = apiGatewayArnTmp[1]
        const method = apiGatewayArnTmp[2]
        let resource = '/' // root resource
        if (apiGatewayArnTmp[3]) {
            resource += apiGatewayArnTmp[3]
        }

        const policy = new AuthPolicy(principalId, awsAccountId, apiOptions)

        // DENY
        policy.denyMethod(AuthPolicy.HttpVerb.POST, "/someEndpoint")

        // PERMIT
        policy.allowMethod(AuthPolicy.HttpVerb.POST, "/someEndpoint")    

        const authResponse = policy.build()

        // YOU CAN EMBED ANYTHING ELSE YOU WANT TO ADD LIKE SO:
        authResponse.context = {
            username: decoded.username,
            someKey: someInfo,
        }

        callback(null, authResponse)

    }) //  jwt.verify(
}
从“jsonwebtoken”导入jwt
导出默认值(事件、上下文、回调)=>{
常量键=“”//{
如果(错误){
console.log('JWT验证错误')
回调(空,响应程序.未授权())
返回
}
const principalId=decoded.user.username
常量apipoptions={}
const tmp=event.methodArn.split(“:”)
常量apiGatewayArnTmp=tmp[5]。拆分(“/”)
const awsAccountId=tmp[4]
apipoptions.region=tmp[3]
apipoptions.restApiId=apiGatewayArnTmp[0]
apipoptions.stage=apiGatewayArnTmp[1]
const method=apiGatewayArnTmp[2]
let resource='/'//根资源
if(apiGatewayArnTmp[3]){
资源+=apiGatewayArnTmp[3]
}
const policy=new AuthPolicy(principalId、awsAccountId、apipoptions)
//否认
policy.denyMethod(AuthPolicy.HttpVerb.POST,“/someEndpoint”)
//许可证
policy.allowMethod(AuthPolicy.HttpVerb.POST,“/someEndpoint”)
const authResponse=policy.build()
//您可以嵌入任何其他要添加的内容,如:
authResponse.context={
用户名:decoded.username,
someKey:someInfo,
}
回调(null,authResponse)
})//jwt.verify(
}
我不记得cognito在其令牌中声明了什么,但是在您jwt.verify之后,只要将解码的令牌记录在控制台日志中,您就会看到来自用户池的大量信息,然后您可以在authResponse.context中传递这些信息,它将出现在您的lambda中的event.requestContext.authorizer下


请记住,标识令牌将包含来自用户池的信息。

好的,所以我所做的是使用CloudLogic调用我的API,并通过POST方法体从Cognito登录传递我的访问令牌。然后,我的后端代码使用CognitoIdentityServiceProvider验证并从该令牌获取用户名。这就是好吧,对吧?