Добавить Cognito Authorizer для всех функций без сервера по умолчанию - PullRequest
0 голосов
/ 15 января 2020

Я хочу добавить cognito authorizer ко всем функциям, объявленным в моем serverless.yml файле. Для этого есть две основные причины:

1) Я хочу не повторять нижеприведенное для каждой отдельной функции

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
          integration: lambda
          authorizer:
            name: authorizer
            arn: arn:aws:cognito-idp:us-east-1:0000:userpool/us-east-1_XXXXXX

2) Я хочу обеспечить безопасность всех конечных точек по умолчанию - важно!

Я создал ниже безсерверный плагин , но не уверен в A) какое событие жизненного цикла мне следует использовать и B) есть ли способ получить идентификатор авторизатора или ARN, не делая api-вызовы ?

class ServerlessCognitoAuthorizer {
  constructor(serverless, options) {
    this.serverless = serverless
    this.options = options
    this.hooks = {
      'package:compileEvents': this.addAuhtorizer.bind(this)
    }
    const region = this.options.region || 'ap-southeast-2'
    const credentials = this.serverless.providers.aws.getCredentials()
    const myCredentials = Object.assign({}, credentials, { region })
    this.apiGateway = new this.serverless.providers.aws.sdk.APIGateway(myCredentials)
  }

  async getApiId() {
    try {
      const result = await this.apiGateway.getRestApis({ limit: 1 }).promise()
      const api = result.items.find(a => a.name === `my-${this.options.stage}-api`)

      if (!api) {
        this.serverless.cli.log('Cannot find REST API to add Cognito Authorizer. Skipping...')
        return null
      }

      return api.id
    } catch (e) {
      this.serverless.cli.log('Error in ServerlessCognitoAuthorizer')
    }
  }

  async getAuthorizer(restApiId) {
    try {
      const result = await this.apiGateway.getAuthorizers({ restApiId, limit: 1 }).promise()
      const authorizerId = result.items[0].id

      if (!authorizerId) {
        this.serverless.cli.log(`Cannot find Cognito Authorizer ID for ${restApiId}`)
        return null
      }

      return authorizerId
    } catch (e) {
      this.serverless.cli.log('Error in ServerlessCognitoAuthorizer')
      throw e
    }
  }

  async addAuhtorizer() {
    const apiId = await this.getApiId()
    let authorizerId
    if (apiId) {
      authorizerId = await this.getAuthorizer(apiId)
    }

    Object.values(this.serverless.service.functions).forEach(slsFunction => {
      const { events, name } = slsFunction

      for (const event of events) {
        const httpEvent = event.http
        if (httpEvent && authorizerId) {
          this.serverless.cli.log(`Adding authorizer config to function ${name}`)
          httpEvent.authorizer = {
            type: 'COGNITO_USER_POOLS',
            authorizerId
          }
        }
      }
    })
  }
}

module.exports = ServerlessCognitoAuthorizer

Кстати, я создаю свой пул когнитивных систем с помощью ресурса формирования облаков ниже:

Resources:
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: ${self:service.name}-${self:provider.stage}-userpool
      UsernameAttributes:
        - email
      AutoVerifiedAttributes:
        - email
      Schema:
        - Name: given_name
          AttributeDataType: String
          Mutable: true
          Required: true
        - Name: family_name
          AttributeDataType: String
          Mutable: true
          Required: true
        - Name: email
          AttributeDataType: String
          Mutable: false
          Required: true
      Policies:
        PasswordPolicy:
            MinimumLength: 10
            RequireLowercase: true
            RequireNumbers: true
            RequireSymbols: false
            RequireUppercase: true
      EmailConfiguration:
          ...
  CognitoUserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      ClientName: ${self:provider.stage}-userpool-client
      AllowedOAuthFlows:
        - code
      AllowedOAuthScopes:
        - phone
        - email
        - openid
      SupportedIdentityProviders:
        - COGNITO
      UserPoolId:
        Ref: CognitoUserPool
      ExplicitAuthFlows:
        - ADMIN_NO_SRP_AUTH
      GenerateSecret: false
      ...
# Print out the Id of the User Pool that is created
Outputs:
  UserPoolId:
    Value:
      Ref: CognitoUserPool

  UserPoolClientId:
    Value:
      Ref: CognitoUserPoolClient
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...