(十六)注册、登录、当前用户与退出
把账号动作集中到另一组路由:
# 项目文件:api_project/src/bookapi/routes/auth.py
from fastapi import APIRouter, Request, Response
from ..dependencies import CurrentIdentity, DbSession
from ..errors import commit_changes
from ..schemas import Credentials, TokenOut, UserOut
from ..security import issue_token, register
router = APIRouter(prefix="/auth", tags=["账户"])
@router.post("/register", response_model=UserOut, status_code=201)
def register_user(data: Credentials, session: DbSession):
return register(session, data)
@router.post("/login", response_model=TokenOut)
def login(data: Credentials, session: DbSession, request: Request):
return issue_token(session, data, request.app.state.settings.token_seconds)
@router.get("/me", response_model=UserOut)
def me(identity: CurrentIdentity):
return identity.user
@router.post("/logout", status_code=204)
def logout(session: DbSession, identity: CurrentIdentity):
with commit_changes(session):
session.delete(identity.token)
return Response(status_code=204) # 204 响应不附带 JSON 正文。注册和登录使用 JSON 请求体,客户端传 username、password。注册交回 UserOut;登录交回 TokenOut。GET /auth/me 只需要当前身份依赖,返回用户对象时,response_model=UserOut 选择公开字段,密码摘要留在服务器。
POST /auth/logout 删除当前令牌记录并提交。下一次携带同一令牌请求时,摘要已经查不到,身份依赖返回 401。一个账号在两个客户端各登录一次,会有两份独立记录,退出当前登录只删除其中一份。
本章请求头由调用者主动添加,服务没有设置自动登录 Cookie。上一章讨论的浏览器 Cookie 写入与 CSRF 要按实际认证方式追踪;接口换成 Bearer 后,重点检查令牌如何保存、发送、到期和撤销。如果另一个前端来源调用 API,浏览器仍会执行 CORS 检查,Authorization 请求头会参与预检,配置方法承接上一章。