redis / node-redis

Redis Node.js client
https://redis.js.org/
MIT License
16.95k stars 1.89k forks source link

Allow `password` to take in a generator/callback to support temporary passwords that must be refreshed. #2779

Closed bgoodman1695 closed 5 months ago

bgoodman1695 commented 5 months ago

Motivation

Use case

Recently AWS introduced an option to connect to ElastiCache instances that are running Redis 7+, using IAM authentication: https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/auth-iam.html

This poses a problem for the typical static password property, e.g. you might write an Elasticache/Redis client code with node-redis like:

import { createClient } from "redis";

const authToken = await generateIAMAuthToken(...);

const client = createClient({
  // ...
  password: authToken,
  // ^ This token will expire in 15 minutes, and the connection will automatically be disconnected after 12 hours!
  //   This forces consumers of the package to implement their own method to manually re-create a client & re-establish a valid connection with a new, valid password before expiry.
});

Proposed Solution

It would be useful if createClient could take in a callback for the password option, that may be invoked on reconnect attempts to properly refresh/regenerate a password in such scenarios where the password may be referring to a temporary auth string that must be refreshed on a TTL.

import { createClient } from "redis";

const client = createClient({
  // ...
  password: async () => generateIAMAuthToken(...),
  // node-redis client should leverage this callback to regenerate a valid password on client disconnect.
  // perhaps include a TTL option to also detect when reusing existing auth may be valid before regenerating?
});

Basic Code Example

No response

devonhumes commented 5 months ago

+1 this is supported in other language clients like Go and Java. In addition to the AWS specific authentication, this provides more flexibility into how credentials are provided in an application.

leibale commented 5 months ago

Duplicate of #821. It's on our roadmap, but no one started implementing it yet. You can use the workaround suggested in https://github.com/redis/node-redis/issues/821#issuecomment-1894291132 in the meantime.

Edit: BTW, do you think we should do it for password only or the whole configuration object?

devonhumes commented 5 months ago

I would lean towards the credentials (i.e. user / password) like other client implementations.