如何在Python中通过HTTP GET请求安全提供静态文件?
Python实现静态文件密码保护方案
对应你提到的PHP/Apache限制静态文件访问的场景,Python可以通过以下两种主流方式实现:
一、HTTP基本认证(触发浏览器密码提示)
这种方式会在用户访问文件URL时,直接触发浏览器自带的密码输入弹窗,验证通过后才能获取文件。适合简单的单密码保护场景,无需单独做登录页面。
实现示例(基于Flask)
from flask import Flask, request, send_from_directory from werkzeug.security import check_password_hash, generate_password_hash app = Flask(__name__) # 预存哈希后的密码(避免明文存储,生产环境建议存在数据库) USER_PASSWORD_HASH = generate_password_hash("your-secure-password") # 静态文件存放目录(不要放在Flask默认的static目录,避免直接访问) PRIVATE_FILES_DIR = "./private_files" @app.route('/protected/<path:filename>') def protected_file(filename): # 获取HTTP基本认证信息 auth = request.authorization if not auth or not check_password_hash(USER_PASSWORD_HASH, auth.password): # 返回401并触发密码提示 return "未授权访问", 401, { "WWW-Authenticate": 'Basic realm="Protected Files"' } # 验证通过,返回文件 return send_from_directory(PRIVATE_FILES_DIR, filename) if __name__ == '__main__': # 生产环境必须用HTTPS,避免密码明文传输 app.run(ssl_context='adhoc', debug=False)
二、会话Cookie验证(基于登录会话)
这种方式需要先让用户通过登录页面输入密码,验证通过后设置会话Cookie,后续访问静态文件时检查会话有效性。适合需要多用户、更灵活权限控制的场景。
实现示例(基于Flask)
from flask import Flask, render_template, request, session, redirect, url_for, send_from_directory app = Flask(__name__) app.secret_key = "your-secret-key-here" # 生产环境要设置为随机安全字符串 PRIVATE_FILES_DIR = "./private_files" # 示例密码,生产环境建议从数据库读取哈希值 VALID_PASSWORD = "your-secure-password" # 登录页面路由 @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': password = request.form.get('password') if password == VALID_PASSWORD: session['authenticated'] = True return redirect(url_for('protected_files_list')) # 跳转到文件列表页 return "密码错误,请重试" return render_template('login.html') # 加载登录表单模板 # 保护静态文件的路由 @app.route('/protected/<path:filename>') def protected_file(filename): if not session.get('authenticated'): return redirect(url_for('login')) return send_from_directory(PRIVATE_FILES_DIR, filename) # 可选:文件列表页面 @app.route('/protected') def protected_files_list(): if not session.get('authenticated'): return redirect(url_for('login')) import os files = os.listdir(PRIVATE_FILES_DIR) return render_template('files_list.html', files=files) if __name__ == '__main__': app.run(ssl_context='adhoc', debug=False)
配套登录模板示例(login.html)
<!DOCTYPE html> <html> <body> <h1>请输入访问密码</h1> <form method="POST"> <input type="password" name="password" required> <button type="submit">登录</button> </form> </body> </html>
关键注意事项
- 生产环境必须用HTTPS:无论是基本认证还是会话验证,都要通过HTTPS传输,防止密码或Cookie被窃取。
- 静态文件存放位置:不要将受保护的文件放在Web服务器的公开静态目录下(比如Nginx默认的html目录),必须通过后端路由统一分发,确保验证逻辑生效。
- 密码存储安全:绝对不要明文存储密码,基本认证场景要用哈希算法(如示例中的
generate_password_hash),会话验证场景建议从数据库读取哈希后的密码。 - 会话安全:生产环境要设置足够复杂的
secret_key,并配置Cookie的secure、httponly属性,防止会话劫持。
内容的提问来源于stack exchange,提问作者Neha
相关产品推荐
相关产品推荐

