Go-Lang Making API Gateway Call via login with AWS Cognito using AWS4 Signer
Go-Lang Making API Gateway Call via login with AWS Cognito using AWS4 Signer
Below is the sample code to making AWS API Gateway call using AWS4 signer
package main import ( "bytes" "context" "encoding/json" "fmt" "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "io/ioutil" "net/http" "time" ) // SignHTTP signs AWS v4 requests with the provided payload hash, service name, region the // request is made to, and time the request is signed at. The signTime allows // you to specify that a request is signed for the future, and cannot be // used until then. // // The payloadHash is the hex encoded SHA-256 hash of the request payload, and // must be provided. Even if the request has no payload (aka body). If the // request has no payload you should use the hex encoded SHA-256 of an empty // string as the payloadHash value. // // "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" // // Some services such as Amazon S3 accept alternative values for the payload // hash, such as "UNSIGNED-PAYLOAD" for reque var hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" var Region = "us-east-1" var Host = "https://sandboxapi.mytest.com/" var PoolId = "us-east-1_123456789" var ClientId = "1234567890" var ServiceName = "execute-api" var IdentityPoolId = Region + ":e8682e09-e7ed-4247-827e-f4e1c7cc3578" var LoginUrl = "https://cognito-idp." + Region + ".amazonaws.com" var IdentityURL = "https://cognito-identity." + Region + ".amazonaws.com/" var USERNAME = "test.user@testdomain.com" var PASSWORD = "Test@123" type AuthenticationResult struct { AccessToken string `json:"AccessToken"` ExpiresIn int64 `json:"ExpiresIn"` IdToken string `json:"IdToken"` RefreshToken string `json:"RefreshToken"` TokenType string `json:"TokenType"` } type LoginResponse struct { AuthenticationResult AuthenticationResult `json:"AuthenticationResult"` } type IdentityResponse struct { IdentityId string `json:"IdentityId"` } type Credentials struct { AccessKeyId string `json:"AccessKeyId"` SecretKey string `json:"SecretKey"` SessionToken string `json:"SessionToken"` } type CredentialsResponse struct { Credentials Credentials `json:"Credentials"` } func Login() AuthenticationResult { fmt.Println("Making Login Call to :- " + LoginUrl) client := &http.Client{} var obj LoginResponse var jsonStr = []byte(`{ "AuthFlow": "USER_PASSWORD_AUTH", "ClientId": "` + ClientId + `", "AuthParameters": { "USERNAME": "` + USERNAME + `", "PASSWORD": "` + PASSWORD + `" }, "ClientMetadata": {} }`) req, _ := http.NewRequest("POST", LoginUrl, bytes.NewBuffer(jsonStr)) req.Header.Set("Content-Type", "application/x-amz-json-1.1") req.Header.Set("x-amz-target", "AWSCognitoIdentityProviderService.InitiateAuth") loginResp, _ := client.Do(req) defer loginResp.Body.Close() bodyLogin, _ := ioutil.ReadAll(loginResp.Body) json.Unmarshal(bodyLogin, &obj) return obj.AuthenticationResult } func GetIdentityId(loginObj AuthenticationResult) IdentityResponse { fmt.Println("Making Identity Call to :- " + IdentityURL) client := &http.Client{} var obj IdentityResponse var jsonStr = []byte(`{ "IdentityPoolId": "` + IdentityPoolId + `", "Logins": { "cognito-idp.` + Region + `.amazonaws.com/` + PoolId + `": "` + loginObj.IdToken + `" } }`) req, _ := http.NewRequest("POST", IdentityURL, bytes.NewBuffer(jsonStr)) req.Header.Set("Content-Type", "application/x-amz-json-1.1") req.Header.Set("x-amz-target", "AWSCognitoIdentityService.GetId") loginResp, _ := client.Do(req) defer loginResp.Body.Close() bodyLogin, _ := ioutil.ReadAll(loginResp.Body) json.Unmarshal(bodyLogin, &obj) return obj } func GetCredentialsForIdentity(loginObj AuthenticationResult, identityObj IdentityResponse) Credentials { fmt.Println("Making Get Credentials Call to :- " + IdentityURL) client := &http.Client{} var obj CredentialsResponse var jsonStr = []byte(`{ "IdentityId": "` + identityObj.IdentityId + `", "Logins": { "cognito-idp.` + Region + `.amazonaws.com/` + PoolId + `": "` + loginObj.IdToken + `" } }`) req, _ := http.NewRequest("POST", IdentityURL, bytes.NewBuffer(jsonStr)) req.Header.Set("Content-Type", "application/x-amz-json-1.1") req.Header.Set("x-amz-target", "AWSCognitoIdentityService.GetCredentialsForIdentity") loginResp, _ := client.Do(req) defer loginResp.Body.Close() bodyLogin, _ := ioutil.ReadAll(loginResp.Body) json.Unmarshal(bodyLogin, &obj) return obj.Credentials } func GetRefreshToken(refreshToken string) AuthenticationResult { fmt.Println("Making Login Call refresh token to :- " + LoginUrl) client := &http.Client{} var obj LoginResponse var jsonStr = []byte(`{ "AuthFlow": "REFRESH_TOKEN_AUTH", "ClientId": "` + ClientId + `", "AuthParameters": { "REFRESH_TOKEN": "` + refreshToken + `" }, "ClientMetadata": {} }`) req, _ := http.NewRequest("POST", LoginUrl, bytes.NewBuffer(jsonStr)) req.Header.Set("Content-Type", "application/x-amz-json-1.1") req.Header.Set("x-amz-target", "AWSCognitoIdentityProviderService.InitiateAuth") loginResp, _ := client.Do(req) defer loginResp.Body.Close() bodyLogin, _ := ioutil.ReadAll(loginResp.Body) json.Unmarshal(bodyLogin, &obj) return obj.AuthenticationResult } func MakeGetAPICall(credentiasObj Credentials, path string) string { host := Host + path fmt.Println("Making Get Call to :- " + host) client := &http.Client{} cfg, _ := config.LoadDefaultConfig(context.TODO(), config.WithCredentialsProvider( credentials.NewStaticCredentialsProvider( credentiasObj.AccessKeyId, credentiasObj.SecretKey, credentiasObj.SessionToken, ), ), ) credentials, _ := cfg.Credentials.Retrieve(context.TODO()) req, _ := http.NewRequest(http.MethodGet, host, nil) signer := v4.NewSigner() _ = signer.SignHTTP(context.TODO(), credentials, req, hash, ServiceName, Region, time.Now()) resp, _ := client.Do(req) defer resp.Body.Close() body, _ := ioutil.ReadAll(resp.Body) return string(body) } func main() { loginObj := Login() identityObj := GetIdentityId(loginObj) credentiasObj := GetCredentialsForIdentity(loginObj, identityObj) var refreshToken AuthenticationResult = GetRefreshToken(loginObj.RefreshToken) loginObj.AccessToken = refreshToken.AccessToken loginObj.IdToken = refreshToken.IdToken body := MakeGetAPICall(credentiasObj, "user/user-service/common/profile") fmt.Println("response Body:", string(body)) }
Steps in making API Gateway Calls:-
- First We login via Cognito to get idToken.
- Then we get AccessId, SecretId and SessionToken via AWS Cognito Identity Provider.
- Then we get a Refresh Token to update the AccessToken and IdToken
- Then we make a HTTP get call using AWS4 Signer.
Required Parameters:-
- PoolId
- AWS Cognito ClientId
- Region
- IdentityPoolId
- Username/Password of Cognito
- Host URL of AWS API Gateway
Comments
Post a Comment