Python中Flask框架的session与cookie传值有什么区别?

flask 中的 session 是 cookie based 的,既然 session 都要被复制一份存到 cookie 里,那还有必要用 session 传值吗?存进 session 里的值还占用内存,直接全存放 cookie 里不就好了吗?

实际使用中总感觉 session get 取值,比 request cookies get 取值的方式,程序要跑的流畅和快一点。这 TM 是心理作用?还是真的是这样( 是 session 的值更新还要 response 一下到 cookie 里的缘故?) flask 中用 session 传值也可以起到用 server 内存空间换速度的作用吗?
Python中Flask框架的session与cookie传值有什么区别?


31 回复

首先 cookie 里面仅仅存放了 session ID,session 本身是不会传到客户端的,然后你再理清楚方案思路


Flask的session和cookie都是用来在HTTP无状态协议下传递数据的,但机制和用途不同。

Cookie是存储在用户浏览器中的纯文本键值对。你通过response.set_cookie()设置,浏览器每次请求都会自动带上。数据完全暴露给用户,不安全,适合存非敏感信息(比如主题偏好)。大小也有限制(约4KB)。

Session是存储在服务器端的数据。Flask默认用加密的cookie(叫session cookie)来存一个session ID,浏览器带着这个ID来请求时,服务器用ID找到对应的数据(比如用户ID)。敏感数据(登录状态)存在服务器更安全。Flask的session本质是一个字典,用起来像session['user_id'] = 1

简单说:cookie把数据存在客户端,session把数据存在服务器(用cookie传个钥匙)。别把密码之类的放cookie里。

总结:按需选,要安全用session。

Flask 是把 session 的值以 json 格式重新编码存入 cookie 里,应该不仅仅是 session ID。我理解的对吗?

session id 一般是一个全局唯一的编号,用算法生成的,例如 guid,访问量规模小的话 crc32,crc64,看你自己的实现

加我们的群问效率更高,一群工程师组建的面向初学者的
Python Linux 学习群,qq 群号:278529278,
Php Linux 学习群,qq 群号:476648701,
非商业性质,拒绝广告,只接收真正想学这方面技术的朋友,交流学习,申请请说明来自 v2ex

基本的 web 常识。

session 存储的方式有很多。比如 cookie,redis,memcache,服务器端文件等等。除了 cookie 存储以外,cookie 中一般只保持 session 的 id 用来获取存储在别处的 session。

采用 cookie 存储 session 的策略的话,session 会被 serialize 之后存到 cookie 里面,所以一般来说没有获取用来序列化这个 session 的暗号的用户,是无法知道 session 里面存的什么内容的。于是一些不允许用户擅自修改的东西可以存到 session 之中。而无所谓用户修改不修改的内容则可以直接存到 cookie 中。

楼上的 真的看过 flask 的实现么?
flask 默认的 session 实现是把 session 处理过之后直接保存到 cookie 中,也叫客户端 session,并不是保存 session id
如果要实现 cookie 中仅仅保存 session id,请使用 flask-session 扩展

保存在 session 中的好处是客户端无法修改(就算是 flask 默认的客户端 session 实现也是加了校验的,如果用户自行修改会被直接拒绝),这样保存用户的登录验证信息的安全性会大大提高
另外就是以后如果你想把 session 保存在 redis memcache 之类的存储中也能快速切换

类似的一般 Session 实现

对的

之前的两个哥们都答错了,水平不敢恭维
flask 默认的 session 实现其实就是 TMD cookie

flask 的 session 不同于其他的实现,完全卸载 cookies 里面的, 用的是他自己写的一个库 itsdangerous 来加密。

特么我说得哪里有问题。

啊呵呵,首先我没有说错,其次请你学会尊重别人的热心回答,再其次,就你下面的理解其实很片面很有可能是错的。

还是有点区别,你直接操作 Cookie 需要自己考虑加解密,但是用 session 的话,加解密逻辑是 Flask 帮你做的。

sorry,手滑多 at 了一个,你的解释其实并没有啥问题,不过上面那个 zsz 就完全是在误导了

flask 的 session 只不过是用 cookie 实现的,并不就等同于 cookie,楼上的 也提到了,是用 itsdangerous 处理过后才放进 cookie 的,这样就不像 cookies 可以被用户直接修改了

Cookie 处理 HTTP 无状态问题
Session 解决状态安全和控制问题

我前面说的是一般情况,一般稍微复杂些的系统会有多系统联合登陆等问题,单纯 flask 放 session 进去没问题,但涉及到不同语言开发的系统还是建议只保存唯一标志在 cookie 中,其他系统识别处理 cookie 中的 session 应该是有难度的,除非有一套统一的设计,有说错的地方见谅

不同语言开发,应该把 user 作为一个服务了吧,请求 flask 提供的 user 服务,取回 decode 过的 session,没难度啊

#5 正解

如果只是简单的 decode,那就是通过 cookie 带出带回数据,请求 flask 提供的 user 服务就还是要在服务端保存用户登录的信息,楼主是想把所有的 session 信息编码在 cookie 中,节省服务器上的内存,这些数据需要频繁的带入带出,而客户端又不读取,规模上去后有不小的流量损耗,而且 session 中一般保存一些状态信息,完全传到客户端是有安全隐患的

而且你说的多系统联合登陆,cookie 本身是不能跨域的。而且和 flask 没关系,我见过绝大部分的框架都支持不同的 session 保存方式

楼主的想把所有的 session,加密序列化放到 cookie 中,不同服务框架间在服务器端无状态情况下,怎么关联好呢



user 服务只提供 client side session 的 encode 和 decode,其本身并不需要保存 session 的内容,使用 cookie 保存 session 并不是楼主想省内存,楼主是选了 flask,flask 默认行为如此,并非楼主意愿体现。

早期可能不需要考虑太多规模上去之后的事情,业务进化的过程中,技术层面也会不断迭代。初期根本不用考虑多语言协作,也不用关注流量和性能,那是日 PV 过了千万之后才要面对的事情。

同意你的看法,楼主用默认的功能满足需求,暂时不需要考虑过复杂,系统一步步迭代就好

而且实际上一般并不会遇到在同一个 session 下还跨语言吧,难道你 /a 和 /b 两个路径下还用了不同的后端来实现?

而且如果真的要实现跨后端 session 就单独用一个 cookie 来保存一个 session id,然后后端用 redis 或者 memcache 共享呗,不过要使用一种通用的序列化方式来保存 session 内容,比如 json 或者 yaml

亲身参与过的几个系统都有这个问题,现实世界也比较难按单个团队的想法去整合,基本还是按照你说的后一种做法 cookie 保存 sid 对接的

以上几位差不多都说的很清楚了,Flask 的确是用 cookie 来保存 session 的,是比较奇特的一种方式,但不用担心安全问题,因为已经加密过了,但记得修改默认密钥。

不过因为是 cookie 存储,所以有浏览器的大小限制,已经存储的对象还得能够序列化和反序列化。除此之外,如果存储太多,来回传输也影响效率。所以 Flask 的作者建议尽量不要往 session 里保存太多东西,不要把 session 当缓存用,而只应该保存关键的 key,比如用户 ID,name 等。

前面有几位回答得挺全面的,直接回答楼主的问题吧,如果不考虑可篡改性的问题,默认 session 和 request.cookies 没太大区别,但 flask 的 session 是个通用框架,建议的做法是把 session 换成存储在服务器端的实现,因为 cookies 请求来回都得带上,数据都带在里面流量浪费了

flask 这个 session 就是个脚手架,给你小规模和测试用起来方便而已
想要换成基于服务器的 session 就是几行代码的事
你现在全放 cookie 里的话,将来改服务端 session 就难了

推荐一个 flask 的入门教程给大家:
[深入浅出 flask](url=http://xc.hubwiz.com/course/562427361bc20c980538e26f?affid=v2ex20180307)

回到顶部