FastAPI 核心安全功能与模板渲染的完整示:登录、CSRF、JWT、会话、认证和缓存功能
以下是一个整合 FastAPI 核心安全功能与模板渲染的完整示例,基于多个技术文档的最佳实践,包含登录、CSRF、JWT、会话、认证和缓存功能:
from datetime import datetime, timedelta
from fastapi import FastAPI, Request, Depends, HTTPException, Form
from fastapi.templating import Jinja2Templates
from fastapi.security import OAuth2PasswordBearer
from fastapi_csrf_protect import CsrfProtect
from fastapi_sessions import SessionManager
from fastapi_sessions.backends.redis import RedisBackend
from jose import jwt
from passlib.context import CryptContext
import aioredis
import os
# ===== 基础配置 =====
app = FastAPI()
templates = Jinja2Templates(directory="templates")
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/login")
# ===== 安全配置 =====
JWT_SECRET = os.getenv("SECRET_KEY", "your_secure_key_123")
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE = timedelta(minutes=30)
# ===== Redis连接 =====
redis = aioredis.from_url("redis://localhost:6379")
session_backend = RedisBackend(redis, prefix="session:", ttl=3600)
session_manager = SessionManager(session_backend)
# ===== CSRF保护 =====
@CsrfProtect.load_config
def get_csrf_config():
return {"secret_key": JWT_SECRET}
# ===== 用户模型 =====
class User:
def __init__(self, username: str, password: str):
self.username = username
self.hashed_password = pwd_context.hash(password)
# 模拟数据库
fake_users_db = {
"admin": User("admin", "secret123")
}
# ===== 核心功能实现 =====
def create_jwt(username: str) -> str:
payload = {
"sub": username,
"exp": datetime.utcnow() + ACCESS_TOKEN_EXPIRE,
"csrf": CsrfProtect.generate_csrf()
}
return jwt.encode(payload, JWT_SECRET, ALGORITHM)
async def get_current_user(
request: Request,
token: str = Depends(oauth2_scheme),
csrf_protect: CsrfProtect = Depends()
):
try:
# 验证CSRF令牌
await csrf_protect.validate_csrf(request)
payload = jwt.decode(token, JWT_SECRET, algorithms=[ALGORITHM])
username = payload.get("sub")
if user := fake_users_db.get(username):
return user
except Exception:
raise HTTPException(401, "Invalid credentials")
# ===== 路由定义 =====
@app.get("/")
async def login_page(request: Request):
return templates.TemplateResponse("login.html", {
"request": request,
"csrf_token": CsrfProtect.generate_csrf()
})
@app.post("/login")
async def login(
request: Request,
username: str = Form(...),
password: str = Form(...),
csrf_protect: CsrfProtect = Depends()
):
# CSRF验证
await csrf_protect.validate_csrf(request)
user = fake_users_db.get(username)
if not user or not pwd_context.verify(password, user.hashed_password):
return templates.TemplateResponse("login.html", {
"request": request,
"error": "Invalid credentials"
})
# 创建会话和JWT
session_id = session_manager.create_session(username)
response = templates.TemplateResponse("dashboard.html", {
"request": request,
"user": username
})
# 设置Cookie
response.set_cookie("session_id", session_id, httponly=True)
response.set_cookie("access_token", create_jwt(username))
return response
@app.get("/dashboard")
async def dashboard(
request: Request,
user: User = Depends(get_current_user)
):
return templates.TemplateResponse("dashboard.html", {
"request": request,
"user": user.username
})
# ===== 缓存实现 =====
from fastapi_cache import FastAPICache
from fastapi_cache.backends.redis import RedisBackend
from fastapi_cache.decorator import cache
FastAPICache.init(RedisBackend(redis), prefix="fastapi-cache")
@app.get("/profile")
@cache(expire=300)
async def user_profile(user: User = Depends(get_current_user)):
return {"username": user.username, "cached_at": datetime.now()}
# ===== 模板文件 =====
"""
<!-- templates/login.html -->
<html>
<head><title>Login</title></head>
<body>
{% if error %}<p style="color:red">{{ error }}</p>{% endif %}
<form method="post">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<input name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Login</button>
</form>
</body>
</html>
<!-- templates/dashboard.html -->
<html>
<head><title>Dashboard</title></head>
<body>
<h1>Welcome {{ user }}!</h1>
<p>Session ID: {{ request.cookies.session_id }}</p>
</body>
</html>
"""
功能说明 (整合多个技术文档)
安全认证体系
• CSRF保护:使用fastapi-csrf-protect中间件,在登录表单中通过隐藏字段传递令牌
• JWT认证:令牌包含用户身份和CSRF令牌双重验证,自动刷新机制
• 会话管理:Redis存储会话数据,支持多设备登录追踪模板交互设计
• 登录页自动注入CSRF令牌到表单
• 错误消息动态渲染(如无效凭证提示)
• 仪表盘展示会话信息和缓存时间缓存优化策略
• Redis缓存用户配置数据,减少数据库查询
• 自动过期机制保证数据新鲜度
• 支持条件缓存(根据用户角色差异化)防御机制
• 密码使用bcrypt算法加密存储
• HTTP-only Cookie存储会话ID
• 双重验证机制(JWT+Session)
部署建议
# 安装依赖
pip install fastapi[all] fastapi-csrf-protect fastapi-sessions python-jose[cryptography] aioredis
# 运行服务
uvicorn main:app --reload --ws-ping-interval 30
该实现综合了以下技术文档的关键点:
• JWT生成与验证流程参考网页1和网页4
• 会话管理采用网页3的Redis存储方案
• 模板交互设计结合网页5和网页7的渲染技术
• 安全策略整合网页2的中间件配置建议
可通过访问 /docs 查看自动生成的API文档,或直接通过浏览器测试登录流程。生产环境建议补充HTTPS配置和密钥轮换机制。
FastAPI 核心安全功能与模板渲染的完整示:登录、CSRF、JWT、会话、认证和缓存功能的更多相关文章
- Vue源码--深入模板渲染
原文链接:https://geniuspeng.github.io/2018/02/07/vue-compile/ 之前整理了vue的响应式原理,在这里有一点是一直很模糊的,就是何时去new一个wat ...
- 【nodejs笔记3】Express基本用法,和路由控制,和模板渲染ejs
1. 路由控制的工作原理 //routes/index.js中的代码//访问主页时,调用ejs模板引擎,渲染index.ejs模板文件,生成静态页面,并显示在浏览器中.router.get('/', ...
- python Django教程 之模板渲染、循环、条件判断、常用的标签、过滤器
python3.5 manage.py runserver python Django教程 之模板渲染.循环.条件判断.常用的标签.过滤器 一.Django模板渲染模板 1. 创建一个 zqxt_tm ...
- 出位的template.js 基于jquery的模板渲染插件
找了好几款基于jquery的模板渲染插件,无一感觉很难用(教程较少.绑定不统一),也可能我智商问题,比如jquery template.js .jtemplate.js. 然后在github上找到这一 ...
- Django模板渲染
一 . 语法 # 关于模板渲染只需要记住两种语法就可以: 1.{{ }} # 里面写变量 2.{% %} # 里面写与逻辑相关的,比如for循环 二 . 变量名 在django的模板语言中按照语法: ...
- day053 url反向解析图解 模板渲染
一.语法 两种特殊符号(语法): {{ }}和 {% %} 变量相关的用{{}},逻辑相关的用{%%}. 二.变量 1. 可直接用 {{ 变量名 }} (可调用字符串, 数字 ,列表,字典,对象等) ...
- web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例
Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...
- flask框架下的jinja2模板引擎(1)(模板渲染)
#转载请留言联系 模板是什么? 在 flask 框架中,视图函数有两个作用:处理业务逻辑和返回响应内容.在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本.模板作用即是承担视图函 ...
- 巨蟒python全栈开发django4:url反向解析图解&&模板渲染
第一部分: 1.(1)知识点回顾: django回顾: ()下载安装 输入网址,a,form表单get post,爬虫 (请求)==>django项目服务端的url(r"index/& ...
- 细说后端模板渲染、客户端渲染、node 中间层、服务器端渲染(ssr)
细说后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr) 前端与后端渲染方式的发展大致经历了这样几个阶段:后端模板渲染.客户端渲染.node 中间层.服务器端渲染(ssr). 1. 后端 ...
随机推荐
- Task异常处理的坑
全局异常 TaskScheduler.UnobservedTaskException += (e, args) =>{ MessageBox.Show("ddddddddddddddd ...
- 永远不要轻易设置Oracle的隐藏参数,哪怕是DRM
这篇文章可能会存在较大争议,甚至颠覆一些人的固有思维. 因为关于Oracle的隐藏参数,江湖上一直都有两派对立的观点: 1.不要设置任何隐藏参数,只有当遇到特殊问题时在售后指导下临时使用,在问题解决后 ...
- websocket-sharp:.NET平台上的WebSocket客户端与服务器开源库
推荐一个C#开发的,实现WebSocket功能的开源项目. 01 项目简介 websocket-sharp提供 WebSocket 客户端和服务器库,基于 C# 开发的,并遵循 WebSocket 协 ...
- UWP 系统通知测试
code: using System; using System.Collections.Generic; using System.IO; using System.Linq; using Syst ...
- w3cschool-HBase官方文档-2数据模型
HBase数据模型 2018-03-03 15:20 更新 HBase数据模型 在 HBase 中,数据模型同样是由表组成的,各个表中又包含数据行和列,在这些表中存储了 HBase 数据.在本节中,我 ...
- Jdk8新特性目录总结
--------------------------------------- Lambda表达式 接口新增方法 四大函数式接口 方法引用 Stream(1) Stream(2) Stream(3) ...
- Elasticsearch(3)--- Docker容器中运行ES、Kibana、Cerebro
想加强ES有关的知识,看了阮一鸣老师讲的<Elasticsearch核心技术与实战>收获很大,所以接下来会跟着他来更加深入的学习ES. 这篇博客的目的就是部署好ES和跟ES相关的辅助工具, ...
- 使用坦克PWA访问助手为自己的局域网应用快速配置免费域名
这篇教程描述如何使用坦克PWA访问助手.这篇文章简称坦克PWA访问助手为PWA助手.PWA结合了DNS服务器技术和HTTP服务器技术实现,因此它需要系统的53端口和80端口.所以,如果你的电脑有程序占 ...
- 测试 【子牙-writing】 大模型
参考:姜子牙大模型系列 | 写作模型ziya-writing开源!开箱即用,快来认领专属你的写作小助手吧 封神榜:https://github.com/IDEA-CCNL/Fengshenbang-L ...
- thewall靶机
includes.php 内有文件读取漏洞 一开始是想着直接用为协议写入一句话木马但是后来发现不行 因为他的文件读取方式长这样 点击查看代码 <?php include ('/var/www/h ...