Username support when connecting to REDIS
See original GitHub issueI created a simple “hello world” chat application running locally using docker-compose which is running redis:6
. However, when I deployed to a production environment on AWS it didn’t work because our ElastiCache Redis Cluster using the 6.2.5
requires a username and password in order to connect.
If you are using docker-compose for development, you can reproduce the error if you configure your Redis service in the following way.
redis:
container_name: redis
image: redis:6
command: ['redis-server', '/etc/redis/redis.conf']
volumes:
- ./redis.conf:/etc/redis/redis.conf
- redis-data:/data
Then in your redis.conf
in your project add the following:
appendonly yes
user myusername +@all allkeys on >my-random-password
Then in your Django settings try the following:
ASGI_APPLICATION = "config.asgi.application"
CHANNEL_LAYERS = {
"default": {
"BACKEND": "channels_redis.core.RedisChannelLayer",
"CONFIG": {
"hosts": ['redis://myusername:my-random-password@redis:6379'],
},
},
}
Relevant package versions:
Python Version: 3.9.10
channels==3.0.4
channels-redis==3.3.1
Django==3.2.12
django-redis-cache==3.0.0
django-redis-sessions==0.6.2
aioredis==1.3.1
In production, I’m running Channels with gunicorn/uvicorn.
This is a traceback of what is happening locally, which leads me to believe that Channels will need to be upgraded to using aioredis 2.0 as well as a fix to this package. It would also be good if the README and docs could be upgraded to show how you’re supposed to configure a Redis host that needs a username and/or password.
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/asgiref/sync.py", line 451, in thread_handler
raise exc_info[1]
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/exception.py", line 38, in inner
response = await get_response(request)
File "/usr/local/lib/python3.9/site-packages/django/core/handlers/base.py", line 233, in _get_response_async
response = await wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/local/lib/python3.9/site-packages/asgiref/sync.py", line 414, in __call__
ret = await asyncio.wait_for(future, timeout=None)
File "/usr/local/lib/python3.9/asyncio/tasks.py", line 442, in wait_for
return await fut
File "/usr/local/lib/python3.9/site-packages/asgiref/current_thread_executor.py", line 22, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.9/site-packages/asgiref/sync.py", line 455, in thread_handler
return func(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/contrib/auth/mixins.py", line 128, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/opt/project/apps/accounts/views.py", line 22, in post
async_to_sync(channel_layer.group_send)(f"push_message_{user.username}", data)
File "/usr/local/lib/python3.9/site-packages/asgiref/sync.py", line 204, in __call__
return call_result.result()
File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 439, in result
return self.__get_result()
File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 391, in __get_result
raise self._exception
File "/usr/local/lib/python3.9/site-packages/asgiref/sync.py", line 270, in main_wrap
result = await self.awaitable(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/channels_redis/core.py", line 671, in group_send
async with self.connection(self.consistent_hash(group)) as connection:
File "/usr/local/lib/python3.9/site-packages/channels_redis/core.py", line 902, in __aenter__
self.conn = await self.pool.pop()
File "/usr/local/lib/python3.9/site-packages/channels_redis/core.py", line 93, in pop
conn = await self.create_conn(loop)
File "/usr/local/lib/python3.9/site-packages/channels_redis/core.py", line 79, in create_conn
return await aioredis.create_redis_pool(**kwargs)
File "/usr/local/lib/python3.9/site-packages/aioredis/commands/__init__.py", line 188, in create_redis_pool
pool = await create_pool(address, db=db,
File "/usr/local/lib/python3.9/site-packages/aioredis/pool.py", line 58, in create_pool
await pool._fill_free(override_min=False)
File "/usr/local/lib/python3.9/site-packages/aioredis/pool.py", line 383, in _fill_free
conn = await self._create_new_connection(self._address)
File "/usr/local/lib/python3.9/site-packages/aioredis/connection.py", line 133, in create_connection
await conn.auth(password)
File "/usr/local/lib/python3.9/site-packages/aioredis/util.py", line 52, in wait_ok
res = await fut
Exception Type: ReplyError at /accounts/send-push-message/
Exception Value: WRONGPASS invalid username-password pair or user is disabled.
Issue Analytics
- State:
- Created 2 years ago
- Comments:7 (5 by maintainers)
@ipmb and @carltongibson,
Thank you for looking into this. On a second pass, I can confirm channels-redis is just passing the address on to aioredis. If you put a break on here, you’ll see that
kwargs
is set to something like the following.My read is that the underlying library doesn’t support it. It was added here, but never made it into an official release afaict. The underlying library is now unsupported/unmaintained, so I think #285 is the blocker.