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

Python CGI实现页面登录拦截:阻止未登录用户访问详情页

在Python CGI中实现类似Django login_required的登录校验功能

嘿,我来帮你搞定这个问题!在CGI环境里确实没有Django那种开箱即用的login_required装饰器,但我们可以手动实现一套登录状态校验逻辑,核心就是用Cookie跟踪用户的登录状态,然后在需要保护的页面脚本里先检查这个状态是否有效。

下面是具体的实现步骤和示例代码:

1. 处理登录逻辑(login1.py)

首先,在登录验证通过后,我们需要给用户设置一个加密的Cookie,用来标记其已登录状态。这个Cookie要尽量安全,避免被篡改或窃取:

#!/usr/bin/env python3
import cgi
import hashlib
import datetime
import os
from http.cookies import SimpleCookie

def main():
    form = cgi.FieldStorage()
    username = form.getvalue("uname")
    password = form.getvalue("psw")

    # 👉 这里替换成你的真实用户验证逻辑(比如从数据库查询哈希后的密码)
    # 注意:绝对不要明文存储或传输密码!实际项目要用bcrypt/passlib等库哈希密码
    valid_user = (username == "test_user" and password == "secure_hash_here")

    print("Content-Type: text/html")
    if valid_user:
        # 生成安全的登录令牌:用用户名+密钥+日期做哈希,避免篡改
        secret_key = os.environ.get("CGI_SECRET_KEY", "your_own_strong_secret")  # 建议存在环境变量
        login_token = hashlib.sha256(
            f"{username}{secret_key}{datetime.datetime.now().strftime('%Y%m%d')}".encode()
        ).hexdigest()

        # 设置Cookie
        cookie = SimpleCookie()
        cookie["logged_in"] = login_token
        cookie["logged_in"]["expires"] = 3600  # 1小时后过期
        cookie["logged_in"]["httponly"] = True  # 禁止JS读取,防XSS
        # 如果是HTTPS环境,加上这行:cookie["logged_in"]["secure"] = True

        print(cookie.output())
        print("Location: details.py\n")  # 登录成功跳转详情页
    else:
        print("\n")
        print("<html><body>登录失败!<a href='login.html'>返回登录页面</a></body></html>")

if __name__ == "__main__":
    main()

2. 保护详情页面(details.py)

在详情页的CGI脚本开头,先检查用户的Cookie是否有效,如果无效就强制跳转到登录页面:

#!/usr/bin/env python3
import hashlib
import datetime
import os
from http.cookies import SimpleCookie

def is_user_logged_in():
    # 读取请求中的Cookie
    cookie = SimpleCookie()
    http_cookie = os.environ.get("HTTP_COOKIE", "")
    cookie.load(http_cookie)

    if "logged_in" not in cookie:
        return False

    # 验证登录令牌的有效性(和login1.py的生成逻辑一致)
    login_token = cookie["logged_in"].value
    username = "test_user"  # 实际项目可从数据库查令牌对应的用户,或存加密的用户Cookie
    secret_key = os.environ.get("CGI_SECRET_KEY", "your_own_strong_secret")
    expected_token = hashlib.sha256(
        f"{username}{secret_key}{datetime.datetime.now().strftime('%Y%m%d')}".encode()
    ).hexdigest()

    return login_token == expected_token

def main():
    # 👉 先执行登录校验,不通过就跳转登录页
    if not is_user_logged_in():
        print("Content-Type: text/html")
        print("Location: login.html\n")
        return

    # 下面是原本的详情页逻辑
    print("Content-Type: text/html\n")
    print("""
    <html>
        <body>
            <h1>欢迎来到详情页面!</h1>
            <p>只有登录用户才能看到这里哦~</p>
            <a href='logout.py'>点击退出登录</a>
        </body>
    </html>
    """)

if __name__ == "__main__":
    main()

3. 退出登录功能(logout.py)

最后,实现退出登录,清除登录状态的Cookie:

#!/usr/bin/env python3
from http.cookies import SimpleCookie

def main():
    print("Content-Type: text/html")
    # 清除登录Cookie(设置为过期)
    cookie = SimpleCookie()
    cookie["logged_in"] = ""
    cookie["logged_in"]["expires"] = -1  # 立即过期
    print(cookie.output())
    print("Location: login.html\n")  # 跳转回登录页

if __name__ == "__main__":
    main()

一些重要的安全提示

  • 密码安全:绝对不要明文存储密码!实际项目中要用bcrypt或passlib等库对密码进行哈希后再存入数据库。
  • 密钥保密:密钥(secret_key)不要硬编码在代码里,最好存在系统环境变量中,避免泄露。
  • HTTPS:生产环境一定要用HTTPS协议,防止Cookie被网络劫持。
  • 复用逻辑:可以把登录校验的is_user_logged_in函数抽成单独的模块,方便在多个需要保护的脚本里复用。

内容的提问来源于stack exchange,提问作者harika

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:28:28