Python之Streamlit登录页面实现

简介: 这是一个基于Streamlit的登录认证系统,依赖`extra-streamlit-components`和`streamlit==1.61.1`。通过调用后端/login接口验证用户名密码,获取`utoken`并存入Cookie;主页面依据`utoken`存在与否自动跳转登录页或导航至Dashboard等模块,并支持退出登录清空凭证。(239字)

依赖包

extra-streamlit-components==0.1.81
streamlit==1.61.1

登录页

登录需要另一个模块提供一个简单的登录接口,body中包含:username和password字段,返回json包括:utoken 字段。utoken 写到cookie中。

import time
from datetime import datetime

import requests
import streamlit as st

from utils.CookieManager import COOKIE_NAME, cookie_manager
from utils.Config import config


def _do_login(username, password):
    """调用后端登录接口换取 utoken 并写入本地 cookie。契约见模块顶部注释。"""
    if not username or not password:
        st.session_state["login_error"] = "用户名和密码不能为空"
        return

    base_url = config.get("sparker").get("base_url")
    url = f"{base_url}/login"
    try:
        resp = requests.post(
            url,
            json={"username": username, "password": password},
            timeout=10,
        )
    except requests.RequestException:
        st.session_state["login_error"] = "服务器错误"
        return

    # 非 200:优先显示响应体中的 detail 字段
    if resp.status_code != 200:
        try:
            detail = resp.json().get("detail")
        except ValueError:
            detail = None
        st.session_state["login_error"] = detail or f"登录失败(HTTP {resp.status_code})"
        return

    try:
        utoken = resp.json().get("utoken")
    except ValueError:
        st.session_state["login_error"] = "登录失败:响应不是合法 JSON"
        return
    if not utoken:
        st.session_state["login_error"] = "登录失败:响应中未包含 utoken"
        return

    # 置 session_state.utoken 并 rerun 跳转主页。cookie 的 set 作为关浏览器重开后的
    # 恢复来源。set 是异步 component 调用,rerun 可能截断指令下发导致 cookie 写不进;
    # 尝试在 set 与 rerun 之间留一段时间,给前端执行 set 写 cookie 的机会。
    cookie_manager.set(
        COOKIE_NAME,
        utoken,
        expires_at=datetime(2026, 12, 31),
    )
    st.session_state.utoken = utoken
    st.session_state.pop("login_error", None)


# 三列布局:标题、提示、表单统一放进中间列,保证左边缘对齐
left, form_col, right = st.columns([1, 2, 1])
with form_col:
    st.markdown("### 登录")
    st.caption("请输入用户名和密码")

    with st.form("login_form"):
        username = st.text_input("用户名", placeholder="请输入用户名")
        password = st.text_input("密码", type="password", placeholder="请输入密码")
        submitted = st.form_submit_button("登录", use_container_width=True)

    if submitted:
        _do_login(username, password)

    if st.session_state.get("login_error"):
        st.error(st.session_state["login_error"])

主体页

以token是否存在,判断登录状态;当然跟严谨的是有校验utoken是否合法的过程。

import time

import streamlit as st

from utils.CookieManager import COOKIE_NAME, cookie_manager

# 居中窄屏布局(聊天界面)
st.set_page_config(
    layout="centered",
    initial_sidebar_state="expanded"
)

login_page = st.Page("layout/login.py", title="Log in", icon=":material/login:")

dashboard = st.Page("layout/dashboard.py", title="Dashboard", icon=":material/dashboard:", default=True)
bugs = st.Page("layout/bugs.py", title="Bug reports", icon=":material/bug_report:")
alerts = st.Page("layout/alerts.py", title="System alerts", icon=":material/notification_important:")

search = st.Page("layout/search.py", title="Search", icon=":material/search:")
history = st.Page("layout/history.py", title="History", icon=":material/history:")

# 登录态以 session_state.utoken 为准(同会话即时生效、可立即跳转)。
# 关浏览器重开后,从本地 cookie 恢复 utoken 到 session_state(CookieManager 读取
# 为异步 component 回传,首帧可能读到空、第二帧才读到真实值,属该机制固有滞后)。
if "utoken" not in st.session_state:
    cookie_utoken = cookie_manager.get(COOKIE_NAME)
    if cookie_utoken:
        st.session_state.utoken = cookie_utoken

if st.session_state.get("utoken"):
    pg = st.navigation(
        {
            "Reports": [dashboard, bugs, alerts],
            "Tools": [search, history],
        }
    )
    # 侧边栏底部退出按钮:清 session_state + 删 cookie,立即回登录页
    with st.sidebar:
        if st.button("退出登录", use_container_width=True):
            st.session_state.pop("utoken", None)
            try:
                cookie_manager.delete(COOKIE_NAME, key=f"del_utoken_{int(time.time() * 1000)}")
                time.sleep(1)
            except KeyError:
                pass
            st.rerun()
else:
    pg = st.navigation([login_page])

pg.run()

(1)layout包下,存放各个示例页面的py文件。

(2)不建议用pages包,不然启动会闪现不合适的侧边栏。


相关文章
|
28天前
|
存储 安全 对象存储
Python之streamlit读写cookie
`extra-streamlit-components` 提供 `CookieManager`,支持在 Streamlit 多页面应用中安全存取 Cookie(如登录态 `utoken`),解决原生不支持设 Cookie 的痛点,需全局单例初始化,避免 key 冲突。(239 字)
|
6月前
|
Java 调度 开发者
Java AQS:JUC 并发体系的底层同步框架基石
AQS(AbstractQueuedSynchronizer)是Java并发包(JUC)的底层核心,以volatile state + CLH双向队列统一实现同步控制。支持独占(如ReentrantLock)与共享(如Semaphore、CountDownLatch)两种模式,通过模板方法封装排队、阻塞/唤醒等通用逻辑,是理解与定制高性能同步组件的关键基石。(239字)
757 7
|
28天前
|
JSON 人工智能 Java
【AI】Agent 全栈进阶|工具调用与结构化输出
文章介绍了大模型的关键能力——Function Calling(函数调用)与结构化输出,主要包含四部分内容: Function Calling 原理,工具定义与注册,JSON Schema 约束输出,最小工具调用循环
147 2
|
28天前
|
JSON 自然语言处理 小程序
节假日查询-假期信息查询 API 接口文档教程
本文为开发者与系统工程师提供阿里云「法定节假日查询」API的权威接入指南,涵盖单参数调用、调休补班识别、多语言示例、免费试用及透明计费等核心能力,助力电商、HR、金融、ERP等场景快速实现假期自动化识别。
194 0
节假日查询-假期信息查询 API 接口文档教程
|
28天前
|
人工智能 数据安全/隐私保护 自然语言处理
阿里云百炼AI通用型节省计划、资源包、Token Plan三种计费方式详解与选型指南
本文介绍了阿里云百炼平台三大核心计费模式的底层差异与选型策略。AI通用型节省计划通过承诺月消费换取阶梯折扣,最高5.3折,覆盖阿里直供全模型,适合长期稳定的多模型混合使用场景;资源包为预付费固定资源量方案,仅支持单一指定模型,灵活性低,适配短期测试、单一模型轻量使用场景;Token Plan采用统一Credits订阅制,全模型通用且支持团队席位管理,成本可控,适合新用户入门试水。文章结合抵扣优先级、适用场景与最新优惠活动,为不同规模的企业和开发者提供精准降本选型指南。
阿里云百炼AI通用型节省计划、资源包、Token Plan三种计费方式详解与选型指南
|
28天前
|
Arthas 监控 Java
阿里程序员常用的 15 款开发者工具!
阿里巴巴将自身在各类业务场景下的技术积淀,通过开源、云上实现或工具等形式对外开放,本文将精选了一些阿里巴巴的开发者工具,希望能帮助开发者们提高开发效率、更优雅的写代码。
298 1
|
28天前
|
自然语言处理 监控 前端开发
Qoder接入OpenBoost MCP,让Agent跑通跨境电商业务
Qoder联合OpenBoost接入MCP协议,将Amazon、TikTok等跨境数据深度融入Agentic编程工作流。开发者仅需自然语言描述需求,Agent即可自动调用工具、生成选品报告、Listing文案或监控仪表盘,实现从代码生成到端到端业务交付的跃迁。
152 0
|
5月前
|
对象存储 Python
Python之DeepAgents自动摘要触发
DeepAgents是基于LangChain的智能体框架,核心特性之一为自动摘要功能:当上下文超长导致模型报错时,自动触发摘要压缩,再重试推理。需显式设置`max_input_tokens`参数启用,支持流式输出摘要日志。
516 3
|
9月前
|
安全 数据安全/隐私保护 Python
Python实现RSA加解密
本文介绍如何使用Python的PyCryptodome库实现RSA加解密。内容包括安装依赖、生成密钥对、保存公私钥文件,以及封装加密、解密和公钥导出功能的类,并提供完整调用示例,适用于安全通信开发场景。(238字)
311 0
|
28天前
|
搜索推荐 Linux API
趁 DeepSeek Harness 刚火,我做了一个 DSH 插件市场,2 天冷启动记录
DeepSeek Harness 插件生态分散难用?DSH Marketplace(dshmarketplace.dev)应运而生:聚合插件、标注兼容性、提供一键安装。支持Web/CLI/Python/API/DSH内置Store等多入口,含自托管插件。开源共建,欢迎用户反馈与作者入驻。(239字)