带有无服务器本地环境的AWS Cognito

时间:2018-10-08 07:20:47

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

这是我们在Github上发现的一个问题,并且存在相同的问题:

  

我们正在使用无服务器和无服务器离线在本地运行lambda。   我们有本地DynamoDB实现。对于Cognito,   serverless-offline模拟已认证的用户和cognitoIdentityId。   模拟用户有权调用lambda,但不能传递   cognitoIdentityId匹配我们在DynamoDB中为用户保存的内容。

     
      
  1. 这可能是无服务器脱机问题,并且可能还有其他问题,   更好的解决方案。
  2.   
  3. 或者可能有一种在本地运行Cognito的方法。
  4.   
  5. 或者我们可以从本地用户访问Cognito。但是我们不知道该怎么做。
  6.   
     

tldr;我不确定开发Labmdas的最佳做法是什么   将Cognito与授权人一起使用时在本地:aws_iam

1 个答案:

答案 0 :(得分:0)

尽管这可能对您的问题有帮助,也可能无济于事,但这是在本地运行时如何模拟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服务以您发送的日期作为正文,函数名称作为x=amz-target标头的一部分执行POST调用。例如,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捕获响应。然后,您可以提取响应正文并在模拟服务器中使用它。