Skip to content

Commit

Permalink
feat: add auth support for Redis 6 (#1130)
Browse files Browse the repository at this point in the history
  • Loading branch information
asyrique authored May 16, 2020
1 parent a345103 commit ad5b455
Show file tree
Hide file tree
Showing 11 changed files with 260 additions and 53 deletions.
1 change: 1 addition & 0 deletions examples/basic_operations.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const Redis = require("ioredis");
const redis = new Redis({
port: process.env.redisPort,
host: process.env.redisEndpoint,
username: process.env.redisUsername,
password: process.env.redisPW,
});

Expand Down
1 change: 1 addition & 0 deletions lib/cluster/ClusterSubscriber.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default class ClusterSubscriber {
this.subscriber = new Redis({
port: options.port,
host: options.host,
username: options.username,
password: options.password,
enableReadyCheck: true,
connectionName: SUBSCRIBER_CONNECTION_NAME,
Expand Down
1 change: 1 addition & 0 deletions lib/cluster/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type NodeRole = "master" | "slave" | "all";
export interface IRedisOptions {
port: number;
host: string;
username?: string;
password?: string;
[key: string]: any;
}
Expand Down
2 changes: 2 additions & 0 deletions lib/connectors/SentinelConnector/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export { ISentinelAddress, SentinelIterator };
export interface ISentinelConnectionOptions extends ITcpConnectionOptions {
role: "master" | "slave";
name: string;
sentinelUsername?: string;
sentinelPassword?: string;
sentinels: Array<Partial<ISentinelAddress>>;
sentinelRetryStrategy?: (retryAttempts: number) => number | void | null;
Expand Down Expand Up @@ -278,6 +279,7 @@ export default class SentinelConnector extends AbstractConnector {
const client = new Redis({
port: endpoint.port || 26379,
host: endpoint.host,
username: this.options.sentinelUsername || null,
password: this.options.sentinelPassword || null,
family:
endpoint.family ||
Expand Down
2 changes: 2 additions & 0 deletions lib/redis/RedisOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export interface IRedisOptions
keepAlive?: number;
noDelay?: boolean;
connectionName?: string;
username?: string;
password?: string;
db?: number;
dropBufferSupport?: boolean;
Expand Down Expand Up @@ -50,6 +51,7 @@ export const DEFAULT_REDIS_OPTIONS: IRedisOptions = {
enableTLSForSentinelMode: false,
updateSentinels: true,
// Status
username: null,
password: null,
db: 0,
// Others
Expand Down
24 changes: 20 additions & 4 deletions lib/redis/event_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,29 @@ export function connectHandler(self) {
return;
}
if (err) {
if (err.message.indexOf("no password is set") === -1) {
flushed = true;
self.recoverFromFatalError(err, err);
} else {
if (err.message.indexOf("no password is set") !== -1) {
console.warn(
"[WARN] Redis server does not require a password, but a password was supplied."
);
} else if (
err.message.indexOf(
"without any password configured for the default user"
) !== -1
) {
console.warn(
"[WARN] This Redis server's `default` user does not require a password, but a password was supplied"
);
} else if (
err.message.indexOf(
"wrong number of arguments for 'auth' command"
) !== -1
) {
console.warn(
`[ERROR] The server returned "wrong number of arguments for 'auth' command". You are probably passing both username and password to Redis version 5 or below. You should only pass the 'password' option for Redis version 5 and under.`
);
} else {
flushed = true;
self.recoverFromFatalError(err, err);
}
}
});
Expand Down
6 changes: 5 additions & 1 deletion lib/redis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const debug = Debug("redis");
* it to reduce the latency.
* @param {string} [options.connectionName=null] - Connection name.
* @param {number} [options.db=0] - Database index to use.
* @param {string} [options.username=null] - If set, client will send AUTH command with this user and password when connected.
* @param {string} [options.password=null] - If set, client will send AUTH command
* with the value of this option when connected.
* @param {boolean} [options.dropBufferSupport=false] - Drop the buffer support for better performance.
Expand Down Expand Up @@ -277,7 +278,10 @@ Redis.prototype.connect = function (callback) {

this.condition = {
select: options.db,
auth: options.password,
auth:
options.username
? [options.username, options.password]
: options.password,
subscriber: false,
};

Expand Down
6 changes: 5 additions & 1 deletion lib/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,11 @@ export function parseURL(url) {

const result: any = {};
if (parsed.auth) {
result.password = parsed.auth.split(":")[1];
const parsedAuth = parsed.auth.split(":");
if (parsedAuth[0]) {
result.username = parsedAuth[0];
}
result.password = parsedAuth[1];
}
if (parsed.pathname) {
if (parsed.protocol === "redis:" || parsed.protocol === "rediss:") {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
],
"scripts": {
"test": "TS_NODE_TRANSPILE_ONLY=true TS_NODE_LOG_ERROR=true NODE_ENV=test mocha \"test/**/*.ts\"",
"test-single": "TS_NODE_TRANSPILE_ONLY=true TS_NODE_LOG_ERROR=true NODE_ENV=test mocha $1",
"lint": "eslint --ext .js,.ts .",
"format": "prettier --write \"{,!(node_modules)/**/}*.{js,ts}\"",
"format-check": "prettier --check \"{,!(node_modules)/**/}*.{js,ts}\"",
Expand Down
Loading

0 comments on commit ad5b455

Please sign in to comment.