AWS API gateway Cognito - Как получить приложение реагирования - PullRequest
0 голосов
/ 09 июня 2019

Я пытаюсь добавить Cognito auth в приложение реагирования, которое тоже вызывает API-шлюз.Я сделал так, чтобы аутентификация была в приложении реакции с:

export default withAuthenticator(App);

Но теперь я дополнительно хочу сделать API-шлюз безопасным с тем же логином.

В настоящее время я получаю эту ошибку:

Доступ к выборке в '... /' from origin 'http://localhost:3000' был заблокирован политикой CORS: Поле заголовка запросаAccess-Control-allow-origin не разрешен Access-Control-Allow-Headers в ответе перед полетом.

Тестировал разные вещи, которые я нашел в Интернете, но на самом деле я не нашел, что именно мне нужноотправить как Авторизация (Является ли token.sessionToken правильной вещью?), а также то, что заголовок дополнительно нуждается.В настоящее время вызов API выглядит следующим образом.

callAPI = async (url) => {
    let token = await Amplify.Auth.currentCredentials();
    console.log(token.sessionToken)
    const apiurl = 'https...?url=' + url
    const response = await fetch(apiurl, {
      method: 'GET',
      mode: 'cors',
      headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH',
        'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, Authorization',
        Authorization: token.sessionToken
      },
    })
    const data = await response.json();

Без сервера шлюза API + соответствующая лямбда:

resources: 
...
  Resources:
...
    CognitoUserPool:
      Type: AWS::Cognito::UserPool
      Properties:
        UserPoolName: ${self:service}_user_pool
        MfaConfiguration: OFF
        UsernameAttributes:
          - email
        Policies:
          PasswordPolicy:
            MinimumLength: 8
            RequireLowercase: False
            RequireNumbers: False
            RequireSymbols: False
            RequireUppercase: False

    CognitoUserPoolClient:
      Type: AWS::Cognito::UserPoolClient
      Properties:
        ClientName: ${self:service}_client
        UserPoolId:
          Ref: CognitoUserPool   

    ApiGatewayAuthorizer: 
      Type: AWS::ApiGateway::Authorizer
      Properties: 
        Name: CognitoUserPool
        Type: COGNITO_USER_POOLS
        IdentitySource: method.request.header.Authorization
        RestApiId: 
          Ref: ApiGatewayRestApi
        ProviderARNs: 
          - Fn::GetAtt:
              - CognitoUserPool
              - Arn

    CognitoIdentityPool:
      Type: AWS::Cognito::IdentityPool
      Properties:
        IdentityPoolName: ${self:service}_identity_pool
        AllowUnauthenticatedIdentities: false
        CognitoIdentityProviders:
          - ClientId:
              Ref: CognitoUserPoolClient
            ProviderName:
              Fn::GetAtt: [CognitoUserPool, ProviderName]

    CognitoIdentityPoolRoles:
      Type: AWS::Cognito::IdentityPoolRoleAttachment
      Properties:
        IdentityPoolId:
          Ref: CognitoIdentityPool
        Roles:
          authenticated:
            Fn::GetAtt: [CognitoAuthRole, Arn]
          unauthenticated:
            Fn::GetAtt: [CognitoUnauthRole, Arn]

    CognitoAuthRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: appAuthRole
        Path: /
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal:
                Federated: "cognito-identity.amazonaws.com"
              Action:
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals:
                  "cognito-identity.amazonaws.com:aud":
                    Ref: CognitoIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": authenticated
        Policies:
          - PolicyName: "CognitoAuthorizedPolicy"
            PolicyDocument:
              Version: "2012-10-17"
              Statement:
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                    - "cognito-identity:*"
                  Resource: "*"
                - Effect: "Allow"
                  Action:
                    - "execute-api:Invoke"
                  Resource: "*"
    CognitoUnauthRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: appUnauthRole
        Path: /
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal:
                Federated: "cognito-identity.amazonaws.com"
              Action:
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals:
                  "cognito-identity.amazonaws.com:aud":
                    Ref: CognitoIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": unauthenticated
        Policies:
          - PolicyName: "CognitoUnauthorizedPolicy"
            PolicyDocument:
              Version: "2012-10-17"
              Statement:
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                    - "cognito-identity:*"
                  Resource: "*"

...

functions:
  ampstoryscreenshotsStep1:
    handler: src/index.ampstoryscreenshotsStep1
    events:
      - http:
          path: '{proxy+}'
          method: get
          cors: true
          integration: lambda
          authorizer: 
              type: COGNITO_USER_POOLS
              authorizerId: 
                Ref: ApiGatewayAuthorizer

Также было бы интересно узнать, как проверить это спочтальон

1 Ответ

0 голосов
/ 11 июня 2019

Хорошо, после проверки документов + некоторый тест, это мое решение. Это создает пул пользователей Cognito, пул удостоверений и аутентификацию для шлюза API

Serverless:

resources: 

  Resources:

...

    CognitoUserPool:
      Type: AWS::Cognito::UserPool
      Properties:
        UserPoolName: ${self:service}_user_pool     
        MfaConfiguration: OFF
        Policies:
          PasswordPolicy:
            MinimumLength: 8
            RequireLowercase: False
            RequireNumbers: False
            RequireSymbols: False
            RequireUppercase: False
        AutoVerifiedAttributes:
          - email

    CognitoUserPoolClient:
      Type: AWS::Cognito::UserPoolClient
      Properties:
        ClientName: ${self:service}_client
        UserPoolId:
          Ref: CognitoUserPool   

    CognitoIdentityPool:
      Type: AWS::Cognito::IdentityPool
      Properties:
        IdentityPoolName: ${self:service}_identity_pool
        AllowUnauthenticatedIdentities: false
        CognitoIdentityProviders:
          - ClientId:
              Ref: CognitoUserPoolClient
            ProviderName:
              Fn::GetAtt: [CognitoUserPool, ProviderName]

    CognitoIdentityPoolRoles:
      Type: AWS::Cognito::IdentityPoolRoleAttachment
      Properties:
        IdentityPoolId:
          Ref: CognitoIdentityPool
        Roles:
          authenticated:
            Fn::GetAtt: [CognitoAuthRole, Arn]
          unauthenticated:
            Fn::GetAtt: [CognitoUnauthRole, Arn]

    CognitoAuthRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: appAuthRole
        Path: /
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal:
                Federated: "cognito-identity.amazonaws.com"
              Action:
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals:
                  "cognito-identity.amazonaws.com:aud":
                    Ref: CognitoIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": authenticated
        Policies:
          - PolicyName: "CognitoAuthorizedPolicy"
            PolicyDocument:
              Version: "2012-10-17"
              Statement:
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                    - "cognito-identity:*"
                  Resource: "*"
                - Effect: "Allow"
                  Action:
                    - "execute-api:Invoke"
                  Resource: "*"

    CognitoUnauthRole:
      Type: AWS::IAM::Role
      Properties:
        RoleName: appUnauthRole
        Path: /
        AssumeRolePolicyDocument:
          Version: "2012-10-17"
          Statement:
            - Effect: "Allow"
              Principal:
                Federated: "cognito-identity.amazonaws.com"
              Action:
                - "sts:AssumeRoleWithWebIdentity"
              Condition:
                StringEquals:
                  "cognito-identity.amazonaws.com:aud":
                    Ref: CognitoIdentityPool
                "ForAnyValue:StringLike":
                  "cognito-identity.amazonaws.com:amr": unauthenticated
        Policies:
          - PolicyName: "CognitoUnauthorizedPolicy"
            PolicyDocument:
              Version: "2012-10-17"
              Statement:
                - Effect: "Allow"
                  Action:
                    - "mobileanalytics:PutEvents"
                    - "cognito-sync:*"
                    - "cognito-identity:*"
                  Resource: "*"

    GatewayResponseDefault4XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
          gatewayresponse.header.Access-Control-Allow-Methods: "'GET,PUT,OPTIONS'"
        ResponseType: DEFAULT_4XX
        RestApiId:
          Ref: 'ApiGatewayRestApi'

    GatewayResponseDefault5XX:
      Type: 'AWS::ApiGateway::GatewayResponse'
      Properties:
        ResponseParameters:
          gatewayresponse.header.Access-Control-Allow-Origin: "'*'"
          gatewayresponse.header.Access-Control-Allow-Headers: "'*'"
          gatewayresponse.header.Access-Control-Allow-Methods: "'GET,PUT,OPTIONS'"
        ResponseType: DEFAULT_5XX
        RestApiId:
          Ref: 'ApiGatewayRestApi'

    ApiGatewayAuthorizer:
      DependsOn:
        - ApiGatewayRestApi
      Type: AWS::ApiGateway::Authorizer
      Properties:
        Name: cognito-authorizer
        IdentitySource: method.request.header.Authorization
        RestApiId:
          Ref: ApiGatewayRestApi
        Type: COGNITO_USER_POOLS
        ProviderARNs:
          - Fn::GetAtt: [CognitoUserPool, Arn]

functions:
  ampstoryscreenshotsStep1:
    handler: src/index.ampstoryscreenshotsStep1
    events:
      - http:
          path: '{proxy+}'
          method: get
          cors: true
          authorizer: 
            type: COGNITO_USER_POOLS
            authorizerId: 
              Ref: ApiGatewayAuthorizer

Порядок здесь важен.

Я спрашиваю так:

callAPI = async (url) => {
    const user = await Amplify.Auth.currentAuthenticatedUser();
    const token = user.signInUserSession.idToken.jwtToken;
    const apiurl = config.apiGateway.URL + '/takescreenshots/?url=' + url

    console.log(apiurl)

    const response = await fetch(apiurl, {
      method: 'GET',
      headers: {
        Authorization: token
      },
    })
    const data = await response.json();

, который просто работает, если вы вошли в систему.

...