From 56a3dbc7b656525eb88e0735e239d56e04a23bee Mon Sep 17 00:00:00 2001 From: janbar Date: Sat, 4 Jun 2022 15:26:04 +0800 Subject: [PATCH] feat: provide a username and password callback method, so that the plaintext username and password will not be stored in the memory, and the username and password will only be generated once when the CredentialsProvider is called. After the method is executed, the username and password strings on the stack will be released. (#2097) Co-authored-by: janbar --- options.go | 3 +++ redis.go | 15 ++++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/options.go b/options.go index a4abe32c..e74f599a 100644 --- a/options.go +++ b/options.go @@ -51,6 +51,9 @@ type Options struct { // or the User Password when connecting to a Redis 6.0 instance, or greater, // that is using the Redis ACL system. Password string + // CredentialsProvider allows the username and password to be updated + // before reconnecting. It should return the current username and password. + CredentialsProvider func() (username string, password string) // Database to be selected after connecting to the server. DB int diff --git a/redis.go b/redis.go index bcf8a2a9..fa57dee3 100644 --- a/redis.go +++ b/redis.go @@ -217,7 +217,12 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { } cn.Inited = true - if c.opt.Password == "" && + username, password := c.opt.Username, c.opt.Password + if c.opt.CredentialsProvider != nil { + username, password = c.opt.CredentialsProvider() + } + + if password == "" && c.opt.DB == 0 && !c.opt.readOnly && c.opt.OnConnect == nil { @@ -228,11 +233,11 @@ func (c *baseClient) initConn(ctx context.Context, cn *pool.Conn) error { conn := newConn(ctx, c.opt, connPool) _, err := conn.Pipelined(ctx, func(pipe Pipeliner) error { - if c.opt.Password != "" { - if c.opt.Username != "" { - pipe.AuthACL(ctx, c.opt.Username, c.opt.Password) + if password != "" { + if username != "" { + pipe.AuthACL(ctx, username, password) } else { - pipe.Auth(ctx, c.opt.Password) + pipe.Auth(ctx, password) } }