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?
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)