AWS API网关Cognito-如何从React应用中获取

时间:2019-06-09 09:39:31

标签: amazon-web-services aws-api-gateway amazon-cognito

我也尝试将Cognito身份验证添加到也调用API网关的react应用程序中。我使它在react应用程序中具有以下身份验证:

export default withAuthenticator(App);

但是现在我还想用相同的登录名来确保API网关的安全。

当前我收到此错误:

  

可以从原点“ http://localhost:3000”以“ ... /”获取   被CORS政策封锁:要求标头栏位   不允许访问控制允许起源   飞行前响应中的Access-Control-Allow-Header。

测试了我在网上找到的不同内容,但是实际上我还没有找到我需要作为授权发送的内容(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网关和相应的lambda:

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 :(得分:0)

检查文档+进行一些测试之后,确定,这是我的解决方案。这将为API网关创建认知用户池,身份池和身份验证

无服务器:

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();

仅在您登录后才能使用。