vibe.d
vibe.d copied to clipboard
A few problems with Redis authentication
I have two problems with connecting to Redis using password authentication.
- RedisSessionStore. Today I tried to initialize RedisSessionStore according to this API, but this API seems doesn't support password authentication. If so please add the feature.
- connectRedisDB I used this manual to connect to my Redis server. But if I use:
auto redisDB = connectRedisDB("redis://password:localhost/3?maxmemory=10000000");
I get the error:
function
vibe.db.redis.redis.connectRedisDB(URL url)
is not callable using argument types(string)
cannot pass argument"redis://password:localhost/3?maxmemory=10000000"
of typestring
to parameterURL url
If I use:
auto redisDB = connectRedisDB(URL("redis://password:localhost/3?maxmemory=10000000"));
I get the error:
std.conv.ConvException@/usr/include/dlang/dmd/std/conv.d(2500): Unexpected 'l' when converting from type string to type uint
----------------
/usr/include/dlang/dmd/std/conv.d:85 pure @safe std.typecons.Tuple!(uint, "data", ulong, "count").Tuple std.conv.parse!(uint, immutable(char)[], 1).parse(ref immutable(char)[]) [0x559f06e04839]
/usr/include/dlang/dmd/std/conv.d:2389 pure @safe ushort std.conv.parse!(ushort, immutable(char)[], 0).parse(ref immutable(char)[]) [0x559f06e0462c]
/usr/include/dlang/dmd/std/conv.d:1970 pure @safe ushort std.conv.toImpl!(ushort, immutable(char)[]).toImpl(immutable(char)[]) [0x559f06dfe630]
/usr/include/dlang/dmd/std/conv.d:224 pure @safe ushort std.conv.to!(ushort).to!(immutable(char)[]).to(immutable(char)[]) [0x559f06dfe60f]
../../../.dub/packages/vibe-d-0.9.4/vibe-d/inet/vibe/inet/url.d:184 pure @safe long vibe.inet.url.URL.__ctor(immutable(char)[]).findPort(immutable(char)[]) [0x559f06f8b436]
../../../.dub/packages/vibe-d-0.9.4/vibe-d/inet/vibe/inet/url.d:199 ref @safe vibe.inet.url.URL vibe.inet.url.URL.__ctor(immutable(char)[]) [0x559f06f8b109]
source/app.d:45 _Dmain [0x559f06d3bc8a
Seems URL thinks localhost is a requested port and tries to convert the host to a port.
P.S.: working code (some override for redis.sessionstore module):
this(string host, long database, ushort port = RedisClient.defaultPort, string password = string.init)
{
URL redisURL = URL("redis", host, port, InetPath(to!string(database)));
if (password != string.init)
redisURL.password = password;
m_db = connectRedisDB(redisURL);
}
auto redisDB = connectRedisDB(URL("redis://password:localhost/3?maxmemory=10000000"));
Shouldn't that be:
auto redisDB = connectRedisDB(URL("redis://:password@localhost/3?maxmemory=10000000"));
auto redisDB = connectRedisDB(URL("redis://password:localhost/3?maxmemory=10000000"));
Shouldn't that be:
auto redisDB = connectRedisDB(URL("redis://:password@localhost/3?maxmemory=10000000"));
Thank you, but I have tried this way. My code:
auto url = URL("redis://test@localhost/1");
logInfo("Password is %s",url.password);
assert(url.password == "test");
Output:
[main(----) INF] Password is
core.exception.AssertError@source/app.d(43): Assertion failure
url.password is the uninitialized value. If I add the line before assertions check I will get no error:
url.password = "test"
Look at the example again: You need to have a column before the password (to indicate that the username is empty). This is not Vibe.d specific BTW, it's the standard URL syntax.
auto redisDB = connectRedisDB(URL("redis://:password@localhost/3?maxmemory=10000000"));
Ok. Copied your code. I get the error:
undefinedobject.Exception@../../../.dub/packages/vibe-d-0.9.4/vibe-d/inet/vibe/inet/url.d(174): Empty user name in URL.
If I use (with space):
auto redisDB = connectRedisDB(URL("redis:// :password@localhost/3"));
I get the error:
undefinedobject.Exception@../../../.dub/packages/vibe-d-0.9.4/vibe-d/redis/vibe/db/redis/redis.d(1469): WRONGPASS invalid username-password pair or user is disabled.
How can I skip check about empty user ?
Actually, you can't. I went and checked the RFC, and it says explicitly:
there is no way to specify a password without specifying a user name
I'm not familiar with redis myself, but googling this looks like a common issue: https://stackoverflow.com/questions/44344628/how-to-create-a-redis-cloud-connection-url-with-an-auth-password/44353927
It however looks like other URL parsers are more permissive and accept no username. CC @s-ludwig .
Actually, you can't. I went and checked the RFC, and it says explicitly:
there is no way to specify a password without specifying a user name
I'm not familiar with redis myself, but googling this looks like a common issue: https://stackoverflow.com/questions/44344628/how-to-create-a-redis-cloud-connection-url-with-an-auth-password/44353927
It however looks like other URL parsers are more permissive and accept no username. CC @s-ludwig .
Ok. I can set up ACL (user & password) in my Redis instance. Using ACL in my web application is suitable for me. But if Redis supports the feature to connect to DB without a username the library for working with Redis also has to support this feature. I'm not a vibe-d developer but I think modifying the URL parser is a bad idea 'cos I can't imagine cases no username requires except Redis. I think more an easy, secure, and efficient way - write a correct parser for Redis only. It's a not hard task. The example in the first message in this topic does this in just 4 lines of code.
Today I've installed a fresh Redis instance in the new node in my home cluster and when I tried to login after failure the redis-cli gave me a tip. The default user is default
. Working code:
settings.sessionStore = new RedisSessionStore("default:password@localhost", 1);
final class RedisSessionStore : SessionStore {
.....
this(string host, ulong database)
{
m_db = connectRedisDB(URL("redis://" ~ host ~ "/" ~ to!string(database)));
}
.....
}
But class RedisSessionStore
uses connectRedis
instead of connectRedisDB
and I can't init session store 'cos I can't set a password
Yes, I just added the same issue.
you can connect by first rc = new RedisClient(host,port), and then rc.auth(password). This is success. But no way for RedisSessionstore.