如何将Django认证用户信息安全传递至Streamlit前端?
Django + Streamlit 用户认证数据互通方案
一、Django 后端实现
1. 依赖安装
pip install django djangorestframework djangorestframework-simplejwt django-cors-headers
2. 项目配置(settings.py)
添加必要的APP和认证、跨域配置:
INSTALLED_APPS = [ # 原有项目APP 'rest_framework', 'rest_framework_simplejwt', 'corsheaders', ] MIDDLEWARE = [ # 原有中间件 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', ] # 允许Streamlit所在域名跨域请求 CORS_ALLOWED_ORIGINS = [ "http://localhost:8501", # Streamlit默认端口,生产环境替换为实际域名 ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', ), } # JWT有效期配置,可按需调整 from datetime import timedelta SIMPLE_JWT = { 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30), 'REFRESH_TOKEN_LIFETIME': timedelta(days=1), }
3. 用户信息接口(views.py)
创建仅认证用户可访问的用户信息视图:
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated from django.contrib.auth.models import User from rest_framework import serializers class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ['id', 'username', 'email', 'first_name', 'last_name'] class CurrentUserView(APIView): permission_classes = [IsAuthenticated] def get(self, request): serializer = UserSerializer(request.user) return Response(serializer.data)
4. URL 配置(urls.py)
挂载登录、token刷新和用户信息接口:
from django.urls import path from rest_framework_simplejwt.views import ( TokenObtainPairView, TokenRefreshView, ) from .views import CurrentUserView urlpatterns = [ # 获取登录token path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), # 刷新access token path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), # 获取当前用户信息 path('api/current-user/', CurrentUserView.as_view(), name='current_user'), ]
二、Streamlit 前端集成
核心逻辑实现
import streamlit as st import requests # Django后端地址,生产环境替换为实际域名 DJANGO_API_URL = "http://localhost:8000" def init_session_state(): if 'access_token' not in st.session_state: st.session_state.access_token = None if 'user_info' not in st.session_state: st.session_state.user_info = None def login(username, password): response = requests.post( f"{DJANGO_API_URL}/api/token/", data={"username": username, "password": password} ) if response.status_code == 200: tokens = response.json() st.session_state.access_token = tokens['access'] return True return False def get_current_user(): if not st.session_state.access_token: return None headers = {"Authorization": f"Bearer {st.session_state.access_token}"} response = requests.get( f"{DJANGO_API_URL}/api/current-user/", headers=headers ) if response.status_code == 200: st.session_state.user_info = response.json() return st.session_state.user_info # token过期或无效,清空状态 st.session_state.access_token = None st.session_state.user_info = None return None # 初始化会话状态 init_session_state() # 登录/已登录界面切换 if not st.session_state.user_info: st.title("用户登录") username = st.text_input("用户名") password = st.text_input("密码", type="password") if st.button("登录"): if login(username, password): st.success("登录成功!") st.rerun() else: st.error("用户名或密码错误") else: st.title(f"欢迎回来,{st.session_state.user_info['first_name'] or st.session_state.user_info['username']}") st.subheader("当前用户信息") st.json(st.session_state.user_info) if st.button("退出登录"): st.session_state.access_token = None st.session_state.user_info = None st.rerun()
三、安全优化建议
- 强制HTTPS传输:生产环境必须启用HTTPS,防止token等敏感数据被明文窃取。
- 严格限制CORS域名:禁止设置
CORS_ALLOW_ALL_ORIGINS = True,仅添加信任的Streamlit部署域名。 - 实现token自动刷新:在Streamlit中检测token过期状态,自动调用
token/refresh接口获取新的access token。 - 加固接口权限:Django视图始终使用
IsAuthenticated权限类,确保未认证请求无法获取用户数据。
内容的提问来源于stack exchange,提问作者Jay Padhiyar
相关产品推荐
相关产品推荐

