Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions docs/SESSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ async def account(session: AuthenticatedSession):
`UserSessionDep` does not check for a user despite its name; it is an alias of `SessionDep`
until 0.4.0, which is planned to make it require one.

`session.user` is set only by passing `user=` to `create_session()` or by assigning it and
saving the session. Keys written to `request.session` (`request.session["user_id"] = ...`)
are application data: the library does not treat them as a login, so `AuthenticatedSession`
still answers `401` for such a session. See
[Regenerate the Session ID After Login](#5-regenerate-the-session-id-after-login) for a login
that sets the user.

### 3. Full Example (Redis Backend)

```python
Expand Down Expand Up @@ -670,6 +677,37 @@ A handler that already holds the request's session object can call
`get_optional_session` and skip the call when it is `None`; `SessionDep` answers `401` to a
visitor who has no session yet.

The example above stores the user ID as application data, which `require_user_session` and
`AuthenticatedSession` do not recognise. To pass them, attach a `SessionUser` after the
rotation and save the session yourself: assigning `session.user` does not mark
`request.session` as modified, so the middleware would not save it.

```python
from fastapi_cachex.session import SessionUser
from fastapi_cachex.session.dependencies import OptionalSession


@app.post("/login")
async def login(request: Request, session: OptionalSession):
... # verify the credentials
user = SessionUser(user_id="123")
if session is not None:
await rotate_session_id(request)
session.user = user
await session_manager.update_session(session)
else:
# No session yet: create one with the user and deliver its token yourself,
# as in the login example in Basic Usage.
_, token = await session_manager.create_session(user=user)
...
return {"ok": True}
```

The complete version, including the cookie for a new visitor, is
[`examples/session_login.py`](https://github.com/allen0099/FastAPI-CacheX/blob/master/examples/session_login.py).
A `login()` helper that does all of this is planned
([#293](https://github.com/allen0099/FastAPI-CacheX/issues/293)).

Outside a middleware, load the session with the same bindings the middleware would pass, and hand
the returned token to the client yourself:

Expand Down
5 changes: 5 additions & 0 deletions fastapi_cachex/session/dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ async def login(request: Request):
return {"ok": True}
```

``request.session["user_id"]`` is application data. For
``require_user_session`` / ``AuthenticatedSession`` to accept the
session, set ``session.user`` after the rotation and save it with
``SessionManager.update_session()``; see the session guide.

Args:
request: FastAPI request object

Expand Down
27 changes: 27 additions & 0 deletions i18n/zh-TW/docs/SESSION.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ async def account(session: AuthenticatedSession):

`UserSessionDep` 雖然名稱如此,卻不會檢查使用者;在 0.4.0 之前它是 `SessionDep` 的別名,0.4.0 預計改為要求使用者。

只有在 `create_session()` 傳入 `user=`,或指定 `session.user` 後儲存 Session,才會設定 `session.user`。寫入 `request.session` 的鍵(`request.session["user_id"] = ...`)是應用程式資料:函式庫不會把它視為登入,因此這種 Session 仍會讓 `AuthenticatedSession` 回應 `401`。會設定使用者的登入方式,請見[登入後重新產生 Session ID](#5-regenerate-the-session-id-after-login)。

### 3. 完整範例(Redis 後端) {#3-full-example-redis-backend}

```python
Expand Down Expand Up @@ -544,6 +546,31 @@ async def login(request: Request):

已經取得請求 Session 物件的 handler,也可以直接呼叫 `await manager.regenerate_session_id(session)`,效果相同。請從 `get_optional_session` 取得 Session,並在它為 `None` 時略過呼叫;`SessionDep` 會對還沒有 Session 的訪客回應 `401`。

上面的範例把使用者 ID 存成應用程式資料,`require_user_session` 與 `AuthenticatedSession` 不會認得它。要通過它們的檢查,請在換 ID 之後附加 `SessionUser`,並自行儲存 Session:指定 `session.user` 不會把 `request.session` 標記為已修改,因此中介軟體不會儲存它。

```python
from fastapi_cachex.session import SessionUser
from fastapi_cachex.session.dependencies import OptionalSession


@app.post("/login")
async def login(request: Request, session: OptionalSession):
... # 驗證帳號密碼
user = SessionUser(user_id="123")
if session is not None:
await rotate_session_id(request)
session.user = user
await session_manager.update_session(session)
else:
# 還沒有 Session:建立帶有使用者的 Session,並自行交付其權杖,
# 做法同基本用法中的登入範例。
_, token = await session_manager.create_session(user=user)
...
return {"ok": True}
```

完整版本(包含為新訪客設定 Cookie)請見 [`examples/session_login.py`](https://github.com/allen0099/FastAPI-CacheX/blob/master/examples/session_login.py)。處理上述所有步驟的 `login()` 輔助函式已在規劃中([#293](https://github.com/allen0099/FastAPI-CacheX/issues/293))。

在中介軟體之外,請以中介軟體會傳入的相同綁定值載入 Session,並自行將回傳的權杖交給用戶端:

```python
Expand Down
Loading