AWS Golang SDK是否包括对Cognito提供商的支持?

I have been using the AWS mobile SDK previously with AWS Cognito. So I have an AWS Cognito Identity Pool configured with 2 AWS IAM roles (authenticated and unauthenticated). Via that I am currently calling some AWS Lambda functions. (btw I am aware of the AWS API Gateway)

I'm trying to do something similar with a Go/Golang client now, i.e. call an AWS Lambda (unauthenticated role) from client side Go, but I can't find an example.

I found this info, but it just seems to be for calling the service functions (ie with environment configured secrets etc. similar to CLI)

https://docs.aws.amazon.com/sdk-for-go/api/service/cognitoidentity/#New

I also looked through the Go AWS SDK source (credentials) and it is almost like the Cognito Provider option has been excluded from the SDK? and I cant find anything that seems to mention 'identityPoolId'.

If that is the case, could I somehow hook into the Javascript exposed interface in Go without using the SDK?

https://docs.aws.amazon.com/cognito/latest/developerguide/getting-credentials.html#getting-credentials-1.javascript

Although I'm thinking I will need to do this without the Javascript SDK too...

ie A direct HTTPS call to AWS backend? Is the AWS Cognito service exposed in this way?

This doesn't seem to be supported within the current SDK. However I found a way to solve this by using the web API. First calling this:

https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetId.html

And once you have the IdendityId calling this:

https://docs.aws.amazon.com/cognitoidentity/latest/APIReference/API_GetCredentialsForIdentity.html

With the returned credentials you have guest/unauthenticated role privilege for calling down to your public Lambda. The IdentityId can be cached locally for subsequent calls.

[edit] work-in-progress example: https://github.com/WhiteHexagon/go2aws

Here's a post I found helpful while I was working on a similar application (accessing a user pool from a Go Lambda): https://benincosa.com/?p=3714

His example should be in the ballpark (at least show you a way forward).

TLDR, adapted

Create a session:

ses, _ := session.NewSession(&aws.Config{Region: aws.String("us-east-1")})

Authenticate from a provider:

params := &cognitoidentityprovider.InitiateAuthInput{
        AuthFlow: aws.String("USER_PASSWORD_AUTH"),
        AuthParameters: map[string]*string{
                "USERNAME": aws.String("maria@vontropps.com"),
                "PASSWORD": aws.String("doremefasolatido"),
        },
        ClientId: aws.String("123456789abcdefghijklmnopq"),
}
cip := cognitoidentityprovider.New(ses)
authResp, _ := cip.InitiateAuth(params)

Get Identity:

   svc := cognitoidentity.New(ses)
   idRes, _ := svc.GetId(&cognitoidentity.GetIdInput{
           IdentityPoolId: aws.String("us-east-1:123456789-444-4444-123456789abc"),
           Logins: map[string]*string{
                   "cognito-idp.<reg>.amazonaws.com/us-east-1_<id>": authResp.AuthenticationResult.IdToken,
           },
   })

   credRes, _ := svc.GetCredentialsForIdentity(&cognitoidentity.GetCredentialsForIdentityInput{
           IdentityId: idRes.IdentityId,
           Logins: map[string]*string{
                   "cognito-idp.<reg>.amazonaws.com/us-east-1_<id>": authResp.AuthenticationResult.IdToken,
           },
   })

Invoke api:

   url := "fill in your endpoint"
   client := new(http.Client)
   req, _ := http.NewRequest("GET", url, nil)

Sign:

   v := v4.NewSigner(credentials.NewStaticCredentials(
          *credRes.Credentials.AccessKeyId,
          *credRes.Credentials.SecretKey,
          *credRes.Credentials.SessionToken,
   ))

   v.Sign(req, nil, "execute-api", "us-east-1", time.Now())

Make Response:

   resp, _ := client.Do(req)

Handle Resp:

   b, _ := ioutil.ReadAll(resp.Body)
   resp.Body.Close()
   fmt.Printf("%s
", b)