Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds auth support for Redis 6 #1130

Merged
merged 5 commits into from May 16, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/basic_operations.js
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
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
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
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
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
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
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
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
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