You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:41:17