mirror of
https://github.com/d3vyce/fastapi-toolsets.git
synced 2026-04-15 22:26:25 +02:00
fix: use URL-safe base64 encoding for cursor tokens (#160)
This commit is contained in:
@@ -255,7 +255,7 @@ The cursor column is set once on [`CrudFactory`](../reference/crud.md#fastapi_to
|
|||||||
!!! note
|
!!! note
|
||||||
`cursor_column` is required. Calling [`cursor_paginate`](../reference/crud.md#fastapi_toolsets.crud.factory.AsyncCrud.cursor_paginate) on a CRUD class that has no `cursor_column` configured raises a `ValueError`.
|
`cursor_column` is required. Calling [`cursor_paginate`](../reference/crud.md#fastapi_toolsets.crud.factory.AsyncCrud.cursor_paginate) on a CRUD class that has no `cursor_column` configured raises a `ValueError`.
|
||||||
|
|
||||||
The cursor value is base64-encoded when returned to the client and decoded back to the correct Python type on the next request. The following SQLAlchemy column types are supported:
|
The cursor value is URL-safe base64-encoded (no padding) when returned to the client and decoded back to the correct Python type on the next request. The following SQLAlchemy column types are supported:
|
||||||
|
|
||||||
| SQLAlchemy type | Python type |
|
| SQLAlchemy type | Python type |
|
||||||
|---|---|
|
|---|---|
|
||||||
|
|||||||
@@ -58,15 +58,20 @@ class _CursorDirection(str, Enum):
|
|||||||
def _encode_cursor(
|
def _encode_cursor(
|
||||||
value: Any, *, direction: _CursorDirection = _CursorDirection.NEXT
|
value: Any, *, direction: _CursorDirection = _CursorDirection.NEXT
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Encode a cursor column value and navigation direction as a base64 string."""
|
"""Encode a cursor column value and navigation direction as a URL-safe base64 string."""
|
||||||
return base64.b64encode(
|
return (
|
||||||
|
base64.urlsafe_b64encode(
|
||||||
json.dumps({"val": str(value), "dir": direction}).encode()
|
json.dumps({"val": str(value), "dir": direction}).encode()
|
||||||
).decode()
|
)
|
||||||
|
.decode()
|
||||||
|
.rstrip("=")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _decode_cursor(cursor: str) -> tuple[str, _CursorDirection]:
|
def _decode_cursor(cursor: str) -> tuple[str, _CursorDirection]:
|
||||||
"""Decode a cursor base64 string into ``(raw_value, direction)``."""
|
"""Decode a URL-safe base64 cursor string into ``(raw_value, direction)``."""
|
||||||
payload = json.loads(base64.b64decode(cursor.encode()).decode())
|
padded = cursor + "=" * (-len(cursor) % 4)
|
||||||
|
payload = json.loads(base64.urlsafe_b64decode(padded).decode())
|
||||||
return payload["val"], _CursorDirection(payload["dir"])
|
return payload["val"], _CursorDirection(payload["dir"])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user