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
相关产品推荐
相关产品推荐

