博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
三、Flask_会话控制与请求钩子
阅读量:6970 次
发布时间:2019-06-27

本文共 4609 字,大约阅读时间需要 15 分钟。

 

 

1. 会话控制

会话控制: cookie 和 session

在flask中会话控制的保存主要通过request和response来完成

session本质上就是保存在服务端中的一个文件,文件中存储了用户的会话信息[我们开发者设置进行的用户登录状态或者访问历史]
session依赖于cookie来实现,因为用户在每次请求服务端时,需要客户端发送属于当前用户的session文件名,一般这个文件名在客户端中使用cookie来保存的,名称一般是session_id

from flask import reuqest # 请求对象 获取cookie信息

from flask import make_response # 响应对象 设置cookie信息

 

 

所谓的会话,就是用户和浏览器中网站之间一次交互过程.

会话的开始是在用户打开浏览器以后第一次访问网站.

会话的结束时在用户关闭浏览器以后

 

因为 http 是一种无状态协议,浏览器请求服务器是无状态的。

无状态:指一次用户请求时,浏览器、服务器无法知道之前这个用户做过什么,每次请求都是一次新的请求。

无状态原因:浏览器与服务器是使用 socket 套接字进行通信的,服务器将请求结果返回给浏览器之后,会关闭当前的 socket 连接,而且服务器也会在处理页面完毕之后销毁页面对象。

有时需要保持下来用户浏览的状态,比如用户是否登录过,浏览过哪些商品等

实现状态保持主要有两种方式:

  • 在客户端存储信息使用Cookie,本地存储,token[jwt,oauth]

  • 在服务器端存储信息使用Session,redis

 

1.1 Cookie

Cookie是由服务器端生成,发送给客户端浏览器,浏览器会将Cookie的key/value保存,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。Cookie的key/value可以由服务器端自己定义。

使用场景: 登录状态, 浏览历史, 网站足迹

 

Cookie是存储在浏览器中的一段纯文本信息,建议不要存储敏感信息如密码,因为电脑上的浏览器可能被其它人使用

Cookie基于域名安全,不同域名的Cookie是不能互相访问的

如访问luffy.com时向浏览器中写了Cookie信息,使用同一浏览器访问baidu.com时,无法访问到luffy.com写的Cookie信息

浏览器的同源策略针对cookie也有限制作用.

当浏览器请求某网站时,会将本网站下所有Cookie信息提交给服务器,所以在request中可以读取Cookie信息

1.1.1 设置cookie

设置cookie需要通过flask的Response响应对象来进行设置,由flask内部提供了一个make_response函数给我们可以快速创建响应对象

from flask import make_response@app.route("/cookie/set_cookie")def set_cookie():    """设置cookie"""    # return "python"    response = make_response("python")  # 这一句代码和上面一句代码是一样    response.set_cookie("uid","100",max_age=30,path="/cookie")    return response

 

1.1.2 获取cookie

@app.route("/demo/get_cookie")def get_cookie():    # 获取cookie    print( request.cookies )    uid = request.cookies.get("uid","cookie失效了")    return uid

 

1.2 Session

对于敏感、重要的信息,建议要存储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息

在服务器端进行状态保持的方案就是Session

注意: Session依赖于Cookie,而且flask中使用session,需要配置SECRET_KEY选项,否则报错.

1.2.1 设置session

from flask import session@app.route("/set_session")def set_session():    """设置session"""    session["user_name"] = "小灰灰"    return "ok"

 

1.2.2 获取session

@app.route("/get_session")def get_session():    """获取session"""    uname = session.get("user_name","session数据没有了")    return uname

 

2. 请求钩子

在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如:

  • 在请求开始时,建立数据库连接;

  • 在请求开始时,根据需求进行权限校验;

  • 在请求结束时,指定数据的交互格式;

为了让每个视图函数避免编写重复功能的代码,Flask提供了通用设置的功能,即请求钩子。

请求钩子是通过装饰器的形式实现,Flask支持如下四种请求钩子:

  • before_first_request

    • 在处理第一个请求前执行

  • before_request

    • 在每次请求前执行

    • 如果在某修饰的函数中返回了一个响应,视图函数将不再被调用

  • after_request

    • 如果没有抛出错误,在每次请求后执行

    • 接受一个参数:视图函数作出的响应

    • 在此函数中可以对响应值在返回之前做最后一步修改处理

    • 需要将参数中的响应在此参数中进行返回

  • teardown_request:

    • 在每次请求后执行

    • 接受一个参数:错误信息,如果有相关错误抛出

    • 需要设置flask的配置DEBUG=False,teardown_request才会接受到异常对象。

"""请求钩子"""@app.before_first_requestdef before_first():    print("项目初始化以后第一次被访问!")@app.before_requestdef before_request():    print("项目每一次被访问,视图执行之前,都会执行这个钩子!")@app.after_requestdef after_request(response):    print("项目每一次被访问,视图执行之后,都会执行这个钩子!")    return response# 使用这个钩子,是在debug=Flase才有效果@app.teardown_requestdef teardown_request(exc):    print("项目每一次被访问,视图执行以后,都会执行这个钩子! 一旦发生错误,会把错误对象传递到当前钩子")    print( exc ) # 异常处理对象
代码参考,以下方代码实现为主

 

from flask import Flaskfrom settings.dev import DevConfigapp = Flask(__name__)# 项目配置app.config.from_object(DevConfig)@app.before_first_requestdef before_first_request():    print("----before_first_request----")    print("系统初始化的时候,执行这个钩子方法")    print("会在接收到第一个客户端请求时,执行这里的代码")@app.before_requestdef before_request():    print("----before_request----")    print("每一次接收到客户端请求时,执行这个钩子方法")    print("一般可以用来判断权限,或者转换路由参数或者预处理客户端请求的数据")@app.after_requestdef after_request(response):    print("----after_request----")    print("在处理请求以后,执行这个钩子方法")    print("一般可以用于记录会员/管理员的操作历史,浏览历史,清理收尾的工作")    response.headers["Content-Type"] = "application/json"    # 必须返回response参数    return response@app.teardown_requestdef teardown_request(exc):    print("----teardown_request----")    print("在每一次请求以后,执行这个钩子方法,如果有异常错误,则会传递错误异常对象到当前方法的参数中")    print(exc)@app.route("/")def index():    print("----视图函数----")    print("视图函数被运行了")    return "视图函数被运行了
"if __name__ == '__main__': app.run(host="0.0.0.0", port=80)
代码实现

在第1次请求时的打印:

----before_first_request----系统初始化的时候,执行这个钩子方法会在接收到第一个客户端请求时,执行这里的代码----before_request----每一次接收到客户端请求时,执行这个钩子方法一般可以用来判断权限,或者转换路由参数或者预处理客户端请求的数据----视图函数----视图函数被运行了----after_request----在处理请求以后,执行这个钩子方法一般可以用于记录会员/管理员的操作历史,浏览历史,清理收尾的工作----teardown_request----在每一次请求以后,执行这个钩子方法,如果有异常错误,则会传递错误异常对象到当前方法的参数中None

在第2次请求时的打印:

----before_request----127.0.0.1 - - [08/Apr/2019 09:23:53] "GET / HTTP/1.1" 200 -每一次接收到客户端请求时,执行这个钩子方法一般可以用来判断权限,或者转换路由参数或者预处理客户端请求的数据----视图函数----视图函数被运行了----after_request----在处理请求以后,执行这个钩子方法一般可以用于记录会员/管理员的操作历史,浏览历史,清理收尾的工作----teardown_request----在每一次请求以后,执行这个钩子方法,如果有异常错误,则会传递错误异常对象到当前方法的参数中None

 

转载于:https://www.cnblogs.com/yijue-lu/p/10952309.html

你可能感兴趣的文章
Win10系列:VC++ Direct3D模板介绍3
查看>>
python 执行sql得到字典格式数据
查看>>
自建docker swarm体验简单之美
查看>>
微信定制开发怎么做?
查看>>
(转载)WPF中的动画——(一)基本概念
查看>>
25.EXTJS 主页面的jsp
查看>>
Verilog语法
查看>>
Atom替换换行符
查看>>
Linux SendMail发送邮件失败诊断案例(四)
查看>>
SpringMVC+hibernate4事务处理
查看>>
大型网站架构演化历程
查看>>
[osg][原]自定义osgGA漫游器
查看>>
JSX 语法
查看>>
Day8 Servlet
查看>>
iOS 集成Protobuf,转换proto文件
查看>>
ZooKeeper伪集群环境搭建
查看>>
[Chromium]怎样安全的使用PostTask
查看>>
python 合并字典,相同 key 的 value 如何相加?
查看>>
Android开发之深入理解Android Studio构建文件build.gradle配置
查看>>
Martini源码剖析
查看>>