Streamlit应用登录组件逻辑异常:登录/登出页面跳转失效
Streamlit登录/登出页面跳转逻辑修复方案
问题核心
当前代码存在以下逻辑混乱问题:
- 登录函数
login()中直接调用run_app()渲染仪表盘内容,导致登录页与仪表盘页面逻辑混杂,跳转机制失效 - 仪表盘页面强制调用
login()并设置page='login',完全违背正常登出流程 authenticator实例未存入会话状态,登出操作无法正确关联全局会话
修改后的代码实现
1. 登录逻辑文件(Streamlit_login.py)
import streamlit as st import mysql.connector from mysql.connector import Error import streamlit_authenticator as stauth from Streamlit_app import run_app # 保留原有的create_connection()、fetch_credentials()、format_credentials()函数 def init_authenticator(): # 将认证器存入会话状态,避免重复初始化 if 'authenticator' not in st.session_state: conn = create_connection() credentials = format_credentials(fetch_credentials(conn)) if credentials: st.session_state['authenticator'] = stauth.Authenticate( credentials=credentials, cookie_name="auth", cookie_key="my_key", cookie_expiry_days=3, ) else: st.error("数据库中未找到用户") conn.close() def login(): init_authenticator() if 'authenticator' not in st.session_state: return None name, auth_status, username = st.session_state['authenticator'].login() if auth_status is None: st.warning("请输入您的账号密码") elif auth_status is False: st.error("用户名或密码错误") # 仅返回验证结果与用户信息,不在这里渲染仪表盘 if auth_status: user_info = st.session_state['authenticator'].credentials['usernames'][username] return { 'auth_status': auth_status, 'first_name': user_info["name"], 'last_name': user_info["last_name"], 'username': username } return {'auth_status': auth_status}
2. 系统页面逻辑文件
import streamlit as st from Streamlit_signup import sign_up from Streamlit_login import login, init_authenticator # 初始化全局会话状态 if 'page' not in st.session_state: st.session_state['page'] = 'login' if 'auth_status' not in st.session_state: st.session_state['auth_status'] = None if 'user_info' not in st.session_state: st.session_state['user_info'] = None init_authenticator() if st.session_state['page'] == 'login': st.title('AI Chatbot') col_1, col_2 = st.columns([14, 2]) with col_2: if st.button(":green[注册]"): st.session_state['page'] = 'sign_up' st.rerun() login_result = login() if login_result and login_result['auth_status']: # 登录成功,保存状态并跳转仪表盘 st.session_state['auth_status'] = True st.session_state['user_info'] = login_result st.session_state['page'] = 'dashboard' st.rerun() elif st.session_state['page'] == 'sign_up': st.title("注册表单") sign_up() if st.button("返回登录"): st.session_state['page'] = 'login' st.session_state['auth_status'] = False st.rerun() elif st.session_state['page'] == 'dashboard': # 拦截未授权访问 if not st.session_state['auth_status']: st.session_state['page'] = 'login' st.rerun() st.title("仪表盘") user_info = st.session_state['user_info'] st.sidebar.subheader(f'欢迎 {user_info["first_name"]} {user_info["last_name"]}!') # 渲染仪表盘核心内容 chat_dir = "your_chat_dir" run_app(chat_dir) # 处理登出逻辑 if st.session_state['authenticator'].logout('退出登录', 'sidebar'): # 登出后重置所有会话状态并跳转登录页 st.session_state['auth_status'] = None st.session_state['user_info'] = None st.session_state['page'] = 'login' st.rerun()
关键修复说明
- 将
authenticator实例存入全局会话,确保认证状态在整个应用生命周期中一致 - 分离登录验证与页面渲染:
login()仅负责账号密码校验,不直接渲染业务内容 - 仪表盘页面独立处理登出操作,点击按钮后重置会话状态并触发应用重跑实现跳转
- 增加未授权访问拦截,防止直接通过URL绕过登录进入仪表盘
内容的提问来源于stack exchange,提问作者Panos Vav
相关产品推荐
相关产品推荐

