0

我的服务在 AWS 集群中运行并使用 Keyspaces。该服务具有角色并获取、、、、、环境变量AWS_SECRET_ACCESS_KEYAWS_ACCESS_KEY_IDAWS_SESSION_TOKENAWS_SECURITY_TOKEN

要连接 Keyspaces,我执行以下操作:


import (
    "context"
    "time"
    
    credentialsV1 "github.com/aws/aws-sdk-go/aws/credentials"
    ec2rolecredsV1 "github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
    ec2metadataV1 "github.com/aws/aws-sdk-go/aws/ec2metadata"
    aws_sess "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sigv4-auth-cassandra-gocql-driver-plugin/sigv4"
    "github.com/gocql/gocql"
)

type Repository struct {
    session *gocql.Session
    ...
}

func (r *Repository) ConnectCassandra(ctx context.Context) {
    awsSession, err := aws_sess.NewSession()

    creds := credentialsV1.NewChainCredentials(
        []credentialsV1.Provider{
            &credentialsV1.EnvProvider{},
            &ec2rolecredsV1.EC2RoleProvider{
                Client: ec2metadataV1.New(awsSession),
            },
        },
    )

    value, err := creds.Get()

    auth := sigv4.NewAwsAuthenticator()
    auth.SessionToken = value.SessionToken
    auth.AccessKeyId = value.AccessKeyID
    auth.SecretAccessKey = value.SecretAccessKey

    cluster := gocql.NewCluster(Host)

    cluster.Timeout = 10 * time.Second
    cluster.ConnectTimeout = 10 * time.Second
    cluster.Consistency = gocql.LocalQuorum
    cluster.Keyspace = Keyspace
    cluster.Port = Port

    cluster.Authenticator = auth

    r.session, err = cluster.CreateSession()

}

func (r *Repository) GetData() (*Data, error) {
    iter := r.session.Query(...)

    scanner := iter.Scanner()

    for scanner.Next() {
        ...
    }
}

该服务定期请求一些数据。一段时间后(〜24小时)我开始收到错误:

2022/02/10 20:29:50 error: failed to connect to XX.XX.XX.XX:9142 due to error: Authentication failure: Session token expired at Wed Feb 09 10:11:42 UTC 2022

同时请求正在运行,没有错误。显然,这意味着最终gocql驱动程序检索到一个令牌。但是为什么我会收到这些错误以及做错了什么?我应该改变什么来停止获取并确保一切正常?

4

1 回答 1

1

ASessionToken是使用您的AccessKeyIdand检索的临时凭证SecretAccessKey。会话令牌有期限,并且只在一段时间内有效。

当它过期时,使用该令牌进行的任何 AWS API 调用都将返回您收到的过期错误。有几种方法可以处理此问题,但实际上您希望通过检索新令牌并重试失败的调用来“刷新”您正在使用的凭据。

查看您的代码,您可能希望在 Repository 结构上定义一个 cred 刷新方法,当遇到特定错误时,可以调用该方法以再次获取新的 cred,然后重试失败的调用。

可以在这里阅读更多信息:https ://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_request.html

于 2022-02-10T20:51:20.950 回答