AWS Cognito with Serverless Local Environment

丶灬走出姿态 提交于 2021-02-16 18:06:46

问题


This is an issue we found on Github and are having the same issue:

We're using serverless and serverless-offline to run lambda locally. We have a local DynamoDB implementation. For Cognito however, serverless-offline mocks the authenticated user and cognitoIdentityId. The mocked user has permission to invoke the lambda but not to pass in the cognitoIdentityId to match what we save in DynamoDB for a user.

  1. This may be a serverless-offline problem, and there may be other, better solutions.
  2. Or there may be a way to run Cognito locally.
  3. Or we can hit Cognito from our local. But we don't know how to do this.

tldr; I'm not sure what the best practice is around developing labmdas locally when using Cognito with authorizer: aws_iam


回答1:


Though this may or may not help with your problem here's how to mock Cognito while running locally.

Every AWS service accepts a configuration. In this configuration you can pass an endpoint parameter. You can pass a local server to this config and mock your desired response for every aws service.

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 services perform a POST call with the date you are sending as the body and the function name as part of the x=amz-target header. For example the AdminGetUser Cognito call has the header: 'x-amz-target': 'AWSCognitoIdentityProviderService.AdminGetUser'

You can create a basic server to handle this like this:


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}`)
})

In order to know what to return I recommend doing some unit tests and capturing the response with nock. You can then extract the response body and use that in your mock server.



来源:https://stackoverflow.com/questions/52697264/aws-cognito-with-serverless-local-environment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!