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包,不然启动会闪现不合适的侧边栏。


相关文章
存储 安全 对象存储
25 0
|
5月前
|
Java 调度 开发者
Java AQS:JUC 并发体系的底层同步框架基石
AQS(AbstractQueuedSynchronizer)是Java并发包(JUC)的底层核心,以volatile state + CLH双向队列统一实现同步控制。支持独占(如ReentrantLock)与共享(如Semaphore、CountDownLatch)两种模式,通过模板方法封装排队、阻塞/唤醒等通用逻辑,是理解与定制高性能同步组件的关键基石。(239字)
692 7
|
11月前
|
机器学习/深度学习 编解码 Python
Python图片上采样工具 - RealESRGANer
Real-ESRGAN基于深度学习实现图像超分辨率放大,有效改善传统PIL缩放的模糊问题。支持多种模型版本,推荐使用魔搭社区提供的预训练模型,适用于将小图高质量放大至大图,放大倍率越低效果越佳。
855 3
|
4月前
|
对象存储 Python
Python之DeepAgents自动摘要触发
DeepAgents是基于LangChain的智能体框架,核心特性之一为自动摘要功能:当上下文超长导致模型报错时,自动触发摘要压缩,再重试推理。需显式设置`max_input_tokens`参数启用,支持流式输出摘要日志。
456 3
|
8月前
|
安全 数据安全/隐私保护 Python
Python实现RSA加解密
本文介绍如何使用Python的PyCryptodome库实现RSA加解密。内容包括安装依赖、生成密钥对、保存公私钥文件,以及封装加密、解密和公钥导出功能的类,并提供完整调用示例,适用于安全通信开发场景。(238字)
291 0
|
8月前
|
API Python
腾讯云-联网搜索API-调用Demo
本文介绍了如何使用Python生成腾讯云API的TC3-HMAC-SHA256签名,并通过Authorization请求头调用SearchPro接口实现搜索功能,涵盖签名计算、请求拼接与HTTP调用全过程。
722 0
|
11月前
|
机器学习/深度学习 PyTorch 算法框架/工具
pytorch基于AnimeFace128数据集训练DCGAN
基于AnimeFace128数据集,使用PyTorch构建DCGAN生成动漫人脸。包含生成器与判别器网络设计、数据加载及训练流程,通过对抗学习生成64×64清晰图像。
424 0
|
4月前
|
人工智能 Java 数据库
DeepAgents 人工介入实战|LangGraph 实现 Agent 高危工具人工审批
本文详解基于 LangChain+LangGraph+DeepAgents 实现 Python 智能体人工介入实战,配置高风险工具中断审批、状态检查点保存与恢复,支持同意 / 拒绝 / 参数编辑,对比 Spring AI Alibaba 方案,附完整可运行源码与生产落地建议。
643 0
|
10月前
|
调度 Python
Python基于Fastapi与APScheduler的应用定时任务
基于FastAPI与APScheduler实现定时任务调度,通过lifespan管理生命周期,每分钟执行一次反馈任务,结合Uvicorn启动服务,构建高效异步任务处理系统。
660 3
|
PyTorch 算法框架/工具 图计算
Python音频处理-频谱图实现
本教程介绍如何使用 PyTorch 提取音频特征,重点实现频谱图的生成。内容包括使用 torchaudio 进行频谱提取、频谱图维度解析、手动实现频谱计算步骤,并对两种方法的结果进行对比分析,展示其差异与实现细节。
1194 0

热门文章

最新文章