【问题标题】:AWS Cognito with Serverless Local Environment具有无服务器本地环境的 AWS Cognito
【发布时间】:2019-03-12 19:54:14
【问题描述】:

这是我们在 Github 上发现的一个问题,并且遇到了同样的问题:

我们使用 serverless 和 serverless-offline 在本地运行 lambda。 我们有一个本地 DynamoDB 实施。然而,对于 Cognito, serverless-offline 模拟经过身份验证的用户和 cognitoIdentityId。 模拟用户有权调用 lambda 但不能传入 cognitoIdentityId 以匹配我们在 DynamoDB 中为用户保存的内容。

  1. 这可能是 serverless-offline 问题,可能还有其他问题, 更好的解决方案。
  2. 或者有办法在本地运行 Cognito。
  3. 或者我们可以从本地访问 Cognito。但我们不知道该怎么做。

tldr;我不确定开发 labmdas 的最佳实践是什么 在本地将 Cognito 与授权方一起使用时:aws_iam

【问题讨论】:

  • 假设这是为了测试目的,我更喜欢在本地模拟 AWS 调用,所以我会传入一些假身份并围绕它定制测试(比如确保它在本地 dynamodb 中,甚至模拟dynamodb 部分)和集成测试,我相信您应该针对真实资源,根本不使用无服务器离线。

标签: amazon-web-services aws-lambda local amazon-cognito serverless


【解决方案1】:

虽然这可能会或可能不会帮助您解决问题,但这里是如何在本地运行时模拟 Cognito。

每个 AWS 服务都接受一个配置。在此配置中,您可以传递 endpoint 参数。您可以将本地服务器传递给此配置,并为每个 aws 服务模拟您想要的响应。

export const getIdentityProvider = () => new CognitoIdentityServiceProvider({
  region: process.env.AWS_REGION,
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  endpoint: process.env.IS_TEST ? 'http://localhost:5001' : null
})

AWS 服务执行 POST 调用,其中您发送的日期作为正文,函数名称作为 x=amz-target 标头的一部分。例如,AdminGetUser Cognito 调用具有标题:'x-amz-target': 'AWSCognitoIdentityProviderService.AdminGetUser'

您可以创建一个基本服务器来处理这个问题:


import http from 'http'
const getBody = async request => {
  return new Promise((resolve, reject) => {
    let body = ''
    request.on('data', (data) => {
      body += data
    })
    request.on('end', () => {
      resolve(JSON.parse(body))
    })
  })
}

const server = http.createServer(async (req, res) => {
  const body = await getBody(req)
  const route = req.headers['x-amz-target']

  let response
  const status = 200

  switch (route) {
    case 'AWSCognitoIdentityProviderService.AdminGetUser':
      response = { foo: 'bar' }
      break
  }

  res.writeHead(response ? status : 404, { 'Content-Type': 'text/plain' })
  res.write(response || 'No route found')
  res.end()
})
server.listen(process.env.PORT || 5001, 'localhost', () => {
  console.log(`Proxy server listening on port http://${server.address().address}:${server.address().port}`)
})

为了知道返回什么,我建议进行一些单元测试并使用nock 捕获响应。然后,您可以提取响应正文并在您的模拟服务器中使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-09
    • 2018-09-13
    • 2017-05-15
    • 1970-01-01
    • 2022-11-10
    • 2019-06-19
    • 2018-07-02
    • 2018-01-19
    相关资源
    最近更新 更多