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