flask web学习之flask与http(三)
一、cookie
HTTP是无状态协议,也就是说,在一次请求响应结束之后,服务器不会留下任何关于对方状态的信息。但是某些信息有事我们必须要记住的,例如用户的登陆状态,这样可以根据状态返回不同的响应。这个地方就需要用到cookie技术。cookie指web服务器为了存储某些数据而保存在浏览器里的小型文本数据。浏览器会第一时间保存它,并在下一次请求的时候携带该数据。cookie通常被用来进行用户会话管理,保存用户的个性化设信息以及和收集用户浏览数据以分析用户行为。
在flask中,想在响应之中添加一个cookie,最方便的方法就是使用Response类提供的set_cookie()方法。
# 响应时携带cookie
from flask import Flask, make_response, request, rediect, url_for
@app.route('/set/<name>')
def set(name)
response = make_response(rediect(url_for('hello')))
response.set_cookie("name", name)
return response
# 请求时获取cookie
@app.route('/')
@app.route('/hello')
def hello():
name = request.args.get("name")
if name is None:
name = request.cookies.get("name", "zhang"))
return name
set_cookie()方法的参数
属性 | 说明 |
---|---|
key | cookie键 |
value | cookie值 |
max_age | cookie被保存的时间数,默认为关闭浏览器时过期 |
expires | 具体过期时间 |
path | 限制cookie在给定路径可用,默认为整个域名 |
domain | 设置可用域名 |
secure | 如果设为true, 只有https协议可用 |
httponly | 如果设为true,禁止客户端js获取 |
二、session
Cookie在web程序中发挥了很大作用,但他有一个致命缺点,就是保存在客户端,可以被手动添加和修改,这样的话会带来一些安全问题。于是我们需要对敏感的cookie进行加密,flask提供了session对象来讲cookie加密保存。
- 设置程序秘钥
程序秘钥可以通过Flask.secret_key属性或者配置变量SECRET_KEY设置。
app.secret_key = "SDADADAIDHAUHUIEHRUIA"
更安全的办法是将secret_key值写入系统环境变量或.env文件中。
import os
app.secret_key = os.getenv("SECRET_KEY", "sadadadadfeea")
- 模拟用户认证
from flask import redirect, session, url_for, reqest, session
@app.route('/login')
def login():
session['login_in'] = True # 写入session
return redirect(url_for('hello')))
@app.route('/')
@app.route('/hello')
def hello():
# 根据用户认证状态返回不同的内容
if "login_in: in session:
return "Authentocated"
else:
return "Not Authentocated"
@app.route('/logout')
def logout()
if "login_in" in session:
session.pop("login_in") # 删除写入数据
return rediect(url_for("hello"))
默认情况下,session cookie会在用户关闭浏览器时删除。我们可以通过session.permanent属性设为True来延长有效期,也可以通过配置PERMANENT_SESSION_LIFETIME设置有效期。尽管session对象会对cookie进行签名加密,但这只能保证内容不被篡改,加密后的数据借助工具还是能够读取,因此,绝对不能再session中存储敏感信息。
三、Flask上下文
Flask中有两种上下文,程序上下文和请求上下文。
1. 上下文变量
Flask中的上下文变量
变量名 | 上下文类别 | 说明 |
---|---|---|
current_app | 程序上下文 | 指向处理请求的当前程序实例 |
g | 程序上下文 | 替代Python的全局变量用法,确保仅在当前请求中可用。用于替代全局数据,每次请求都会重设。 |
request | 请求上下文 | 封装客户发出的请求报文数据 |
session | 请求上下文 | 用于记住请求之间的数据,通过签名的cookie实现 |
from flask imort g
@app.before_request
def get_name():
g.name = request.args.get('name')
# 因为g存储在程序上下文中,且每次都会随请求重设。我们可以通过它来结合请求钩子来保存每个请求处理前所需要的全局变量,比如登入的用户对象、数据库连接等。
2. 激活上下文
在下面情况下,Flask会自动激活上下文:
- 使用flask run 启动程序
- 使用app.rum()启动程序
- 执行@app.ccli,command()装饰器注册新的flask命令时
- 使用flask shell启动Python shell时
手动激活上下文:
from app import app
from flask import current_app
# 使用with语句执行上下文操作
with app.app_context():
print(current_app.name)
# 显式的使用push()方法推送(激活)上下文,在执行完操作时使用pop()方法销毁
app_ctx = app.app_context()
app_ctx.push()
print(current_app.name)
app_ctx.pop()
# 通过test_request_context()临时创建上下文
with app.test_request_context('/hello'):
print(request.method)
3. 上下文钩子
flask为上下文提供了一个teardown_appcontext()钩子,使用它注册的回调函数会在程序上下文被销毁时调用,而且通常也会在请求上下文被销毁时调用。
# 在每个请求处理结束后销毁数据库连接
@app.teardown_appcontext
def teardown_db(exception):
db.close()
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!