mirror of
https://github.com/fastapi-users/fastapi-users.git
synced 2026-03-13 07:49:55 +08:00
Fix #1043: Add a prefix to the generated key in RedisStrategy
This commit is contained in:
@@ -26,6 +26,7 @@ As you can see, instantiation is quite simple. It accepts the following argument
|
||||
|
||||
* `redis` (`redis.asyncio.Redis`): An instance of `redis.asyncio.Redis`. Note that the `decode_responses` flag set to `True` is necessary.
|
||||
* `lifetime_seconds` (`Optional[int]`): The lifetime of the token in seconds. Defaults to `None`, which means the token doesn't expire.
|
||||
* `key_prefix` (`str`): The prefix used to set the key in the Redis stored. Defaults to `fastapi_users_token:`.
|
||||
|
||||
!!! tip "Why it's inside a function?"
|
||||
To allow strategies to be instantiated dynamically with other dependencies, they have to be provided as a callable to the authentication backend.
|
||||
|
||||
@@ -10,10 +10,15 @@ from fastapi_users.manager import BaseUserManager
|
||||
|
||||
class RedisStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID]):
|
||||
def __init__(
|
||||
self, redis: redis.asyncio.Redis, lifetime_seconds: Optional[int] = None
|
||||
self,
|
||||
redis: redis.asyncio.Redis,
|
||||
lifetime_seconds: Optional[int] = None,
|
||||
*,
|
||||
key_prefix: str = "fastapi_users_token:",
|
||||
):
|
||||
self.redis = redis
|
||||
self.lifetime_seconds = lifetime_seconds
|
||||
self.key_prefix = key_prefix
|
||||
|
||||
async def read_token(
|
||||
self, token: Optional[str], user_manager: BaseUserManager[models.UP, models.ID]
|
||||
@@ -21,7 +26,7 @@ class RedisStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID
|
||||
if token is None:
|
||||
return None
|
||||
|
||||
user_id = await self.redis.get(token)
|
||||
user_id = await self.redis.get(f"{self.key_prefix}{token}")
|
||||
if user_id is None:
|
||||
return None
|
||||
|
||||
@@ -33,8 +38,10 @@ class RedisStrategy(Strategy[models.UP, models.ID], Generic[models.UP, models.ID
|
||||
|
||||
async def write_token(self, user: models.UP) -> str:
|
||||
token = secrets.token_urlsafe()
|
||||
await self.redis.set(token, str(user.id), ex=self.lifetime_seconds)
|
||||
await self.redis.set(
|
||||
f"{self.key_prefix}{token}", str(user.id), ex=self.lifetime_seconds
|
||||
)
|
||||
return token
|
||||
|
||||
async def destroy_token(self, token: str, user: models.UP) -> None:
|
||||
await self.redis.delete(token)
|
||||
await self.redis.delete(f"{self.key_prefix}{token}")
|
||||
|
||||
@@ -68,7 +68,7 @@ class TestReadToken:
|
||||
redis: RedisMock,
|
||||
user_manager,
|
||||
):
|
||||
await redis.set("TOKEN", "bar")
|
||||
await redis.set(f"{redis_strategy.key_prefix}TOKEN", "bar")
|
||||
authenticated_user = await redis_strategy.read_token("TOKEN", user_manager)
|
||||
assert authenticated_user is None
|
||||
|
||||
@@ -79,7 +79,9 @@ class TestReadToken:
|
||||
redis: RedisMock,
|
||||
user_manager,
|
||||
):
|
||||
await redis.set("TOKEN", "d35d213e-f3d8-4f08-954a-7e0d1bea286f")
|
||||
await redis.set(
|
||||
f"{redis_strategy.key_prefix}TOKEN", "d35d213e-f3d8-4f08-954a-7e0d1bea286f"
|
||||
)
|
||||
authenticated_user = await redis_strategy.read_token("TOKEN", user_manager)
|
||||
assert authenticated_user is None
|
||||
|
||||
@@ -91,7 +93,7 @@ class TestReadToken:
|
||||
user_manager,
|
||||
user,
|
||||
):
|
||||
await redis.set("TOKEN", str(user.id))
|
||||
await redis.set(f"{redis_strategy.key_prefix}TOKEN", str(user.id))
|
||||
authenticated_user = await redis_strategy.read_token("TOKEN", user_manager)
|
||||
assert authenticated_user is not None
|
||||
assert authenticated_user.id == user.id
|
||||
@@ -104,7 +106,7 @@ async def test_write_token(
|
||||
):
|
||||
token = await redis_strategy.write_token(user)
|
||||
|
||||
value = await redis.get(token)
|
||||
value = await redis.get(f"{redis_strategy.key_prefix}{token}")
|
||||
assert value == str(user.id)
|
||||
|
||||
|
||||
@@ -113,8 +115,8 @@ async def test_write_token(
|
||||
async def test_destroy_token(
|
||||
redis_strategy: RedisStrategy[UserModel, IDType], redis: RedisMock, user
|
||||
):
|
||||
await redis.set("TOKEN", str(user.id))
|
||||
await redis.set(f"{redis_strategy.key_prefix}TOKEN", str(user.id))
|
||||
|
||||
await redis_strategy.destroy_token("TOKEN", user)
|
||||
|
||||
assert await redis.get("TOKEN") is None
|
||||
assert await redis.get(f"{redis_strategy.key_prefix}TOKEN") is None
|
||||
|
||||
Reference in New Issue
Block a user