Flask 示例:设置 HttpOnly Cookie 存储 JWT
from flask import Flask, make_response, request, jsonify
import jwt
import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key'
@app.route('/login', methods=['POST'])
def login():
# 模拟登录成功后的用户信息
user_id = 123
token = jwt.encode(
{'user_id': user_id, 'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)},
app.config['SECRET_KEY'],
algorithm='HS256'
)
# 创建响应对象
resp = make_response(jsonify({'message': '登录成功'}))
# 设置 HttpOnly Cookie
resp.set_cookie(
'access_token', # Cookie 名称
token, # Cookie 值(JWT)
httponly=True, # 禁止 JS 访问,防 XSS
secure=False, # 生产环境应设为 True(仅 HTTPS)
samesite='Lax', # 防 CSRF,推荐 Lax 或 Strict
max_age=3600 # 有效期 1 小时
)
return resp
@app.route('/protected')
def protected():
token = request.cookies.get('access_token')
if not token:
return jsonify({'error': '未授权'}), 401
try:
payload = jwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
return jsonify({'user_id': payload['user_id']})
except jwt.ExpiredSignatureError:
return jsonify({'error': 'Token 已过期'}), 401
解析亮点
set_cookie()
设置了 HttpOnly 属性,防止 JS 访问。secure=False
仅用于开发环境,生产环境必须启用 HTTPS。samesite='Lax'
防止跨站请求伪造(CSRF)。request.cookies.get()
用于读取 Cookie 中的 Token。
Django 示例:设置 HttpOnly Cookie 存储 JWT
from rest_framework.views import APIView
from rest_framework.response import Response
from django.conf import settings
from django.utils import timezone
import jwt
class LoginView(APIView):
def post(self, request):
user_id = 123 # 模拟登录成功
payload = {
'user_id': user_id,
'exp': timezone.now() + timezone.timedelta(hours=1)
}
token = jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256')
response = Response({'message': '登录成功'})
# 设置 HttpOnly Cookie
response.set_cookie(
key='access_token',
value=token,
httponly=True,
secure=not settings.DEBUG,
samesite='Lax',
max_age=3600
)
return response
class ProtectedView(APIView):
def get(self, request):
token = request.COOKIES.get('access_token')
if not token:
return Response({'error': '未授权'}, status=401)
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=['HS256'])
return Response({'user_id': payload['user_id']})
except jwt.ExpiredSignatureError:
return Response({'error': 'Token 已过期'}, status=401)
解析亮点
response.set_cookie()
设置 HttpOnly Cookie。secure=not settings.DEBUG
:开发环境允许 HTTP,生产强制 HTTPS。request.COOKIES.get()
读取 Cookie 中的 Token。使用
jwt.decode()
验证 Token 合法性和过期时间。
安全建议(适用于 Flask 和 Django)
项目 | 建议配置 |
---|---|
httponly |
✅ 必须开启,防止 XSS |
secure |
✅ 生产环境必须开启 HTTPS |
samesite |
✅ 推荐 'Lax' 或 'Strict' |
max_age |
根据业务设置有效期 |
Token刷新 | 建议使用 Refresh Token + 自动刷新机制 |