V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
rogwan
V2EX  ›  Python

Flask 中通过 session 或 cookie 传值,有什么区别吗?

  •  
  •   rogwan · 2017-04-30 08:06:15 +08:00 via Android · 6286 次点击
    这是一个创建于 2793 天前的主题,其中的信息可能已经有所发展或是发生改变。
    flask 中的 session 是 cookie based 的,既然 session 都要被复制一份存到 cookie 里,那还有必要用 session 传值吗?存进 session 里的值还占用内存,直接全存放 cookie 里不就好了吗?

    实际使用中总感觉 session get 取值,比 request cookies get 取值的方式,程序要跑的流畅和快一点。这 TM 是心理作用?还是真的是这样( 是 session 的值更新还要 response 一下到 cookie 里的缘故?) flask 中用 session 传值也可以起到用 server 内存空间换速度的作用吗?
    30 条回复    2018-03-07 11:53:38 +08:00
    zsz
        1
    zsz  
       2017-04-30 08:33:26 +08:00 via iPhone
    @rogwan 首先 cookie 里面仅仅存放了 session ID,session 本身是不会传到客户端的,然后你再理清楚方案思路
    rogwan
        2
    rogwan  
    OP
       2017-04-30 08:42:27 +08:00 via Android
    @zsz Flask 是把 session 的值以 json 格式重新编码存入 cookie 里,应该不仅仅是 session ID。我理解的对吗?
    zsz
        3
    zsz  
       2017-04-30 08:56:53 +08:00 via iPhone
    session id 一般是一个全局唯一的编号,用算法生成的,例如 guid,访问量规模小的话 crc32,crc64,看你自己的实现

    加我们的群问效率更高,一群工程师组建的面向初学者的
    Python Linux 学习群,qq 群号:278529278,
    Php Linux 学习群,qq 群号:476648701,
    非商业性质,拒绝广告,只接收真正想学这方面技术的朋友,交流学习,申请请说明来自 v2ex
    gyorou
        4
    gyorou  
       2017-04-30 09:00:09 +08:00
    基本的 web 常识。

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

    采用 cookie 存储 session 的策略的话,session 会被 serialize 之后存到 cookie 里面,所以一般来说没有获取用来序列化这个 session 的暗号的用户,是无法知道 session 里面存的什么内容的。于是一些不允许用户擅自修改的东西可以存到 session 之中。而无所谓用户修改不修改的内容则可以直接存到 cookie 中。
    wwqgtxx
        5
    wwqgtxx  
       2017-04-30 09:31:04 +08:00
    楼上的 @zsz @gyorou 真的看过 flask 的实现么?
    flask 默认的 session 实现是把 session 处理过之后直接保存到 cookie 中,也叫客户端 session,并不是保存 session id
    如果要实现 cookie 中仅仅保存 session id,请使用 flask-session 扩展

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

    TheCure
        7
    TheCure  
       2017-04-30 09:41:25 +08:00
    @wwqgtxx 对的

    之前的两个哥们都答错了,水平不敢恭维
    flask 默认的 session 实现其实就是 TMD cookie
    KKKKKK
        8
    KKKKKK  
       2017-04-30 09:51:39 +08:00
    flask 的 session 不同于其他的实现,完全卸载 cookies 里面的, 用的是他自己写的一个库 itsdangerous 来加密。
    gyorou
        9
    gyorou  
       2017-04-30 09:58:19 +08:00
    @wwqgtxx 特么我说得哪里有问题。
    gyorou
        10
    gyorou  
       2017-04-30 10:04:43 +08:00
    @callofmx 啊呵呵,首先我没有说错,其次请你学会尊重别人的热心回答,再其次,就你下面的理解其实很片面很有可能是错的。
    Citrus
        11
    Citrus  
       2017-04-30 10:07:05 +08:00 via iPhone
    还是有点区别,你直接操作 Cookie 需要自己考虑加解密,但是用 session 的话,加解密逻辑是 Flask 帮你做的。
    wwqgtxx
        12
    wwqgtxx  
       2017-04-30 10:47:27 +08:00 via iPhone
    @gyorou sorry,手滑多 at 了一个,你的解释其实并没有啥问题,不过上面那个 zsz 就完全是在误导了
    wwqgtxx
        13
    wwqgtxx  
       2017-04-30 10:49:22 +08:00 via iPhone
    @callofmx flask 的 session 只不过是用 cookie 实现的,并不就等同于 cookie,楼上的 @KKKKKK 也提到了,是用 itsdangerous 处理过后才放进 cookie 的,这样就不像 cookies 可以被用户直接修改了
    kfll
        14
    kfll  
       2017-04-30 11:24:43 +08:00 via Android
    Cookie 处理 HTTP 无状态问题
    Session 解决状态安全和控制问题
    zsz
        15
    zsz  
       2017-04-30 11:48:34 +08:00 via iPhone
    @callofmx 我前面说的是一般情况,一般稍微复杂些的系统会有多系统联合登陆等问题,单纯 flask 放 session 进去没问题,但涉及到不同语言开发的系统还是建议只保存唯一标志在 cookie 中,其他系统识别处理 cookie 中的 session 应该是有难度的,除非有一套统一的设计,有说错的地方见谅
    sagaxu
        16
    sagaxu  
       2017-04-30 12:51:16 +08:00
    @zsz 不同语言开发,应该把 user 作为一个服务了吧,请求 flask 提供的 user 服务,取回 decode 过的 session,没难度啊
    guyskk
        17
    guyskk  
       2017-04-30 13:07:36 +08:00
    @wwqgtxx #5 正解
    zsz
        18
    zsz  
       2017-04-30 13:20:30 +08:00 via iPhone
    @sagaxu 如果只是简单的 decode,那就是通过 cookie 带出带回数据,请求 flask 提供的 user 服务就还是要在服务端保存用户登录的信息,楼主是想把所有的 session 信息编码在 cookie 中,节省服务器上的内存,这些数据需要频繁的带入带出,而客户端又不读取,规模上去后有不小的流量损耗,而且 session 中一般保存一些状态信息,完全传到客户端是有安全隐患的
    jy01264313
        19
    jy01264313  
       2017-04-30 13:28:40 +08:00
    @wwqgtxx 正解+1
    jy01264313
        20
    jy01264313  
       2017-04-30 13:33:18 +08:00
    @zsz 而且你说的多系统联合登陆,cookie 本身是不能跨域的。而且和 flask 没关系,我见过绝大部分的框架都支持不同的 session 保存方式
    zsz
        21
    zsz  
       2017-04-30 13:43:23 +08:00 via iPhone
    @jy01264313 楼主的想把所有的 session,加密序列化放到 cookie 中,不同服务框架间在服务器端无状态情况下,怎么关联好呢
    sagaxu
        22
    sagaxu  
       2017-04-30 13:44:29 +08:00
    @zsz

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

    早期可能不需要考虑太多规模上去之后的事情,业务进化的过程中,技术层面也会不断迭代。初期根本不用考虑多语言协作,也不用关注流量和性能,那是日 PV 过了千万之后才要面对的事情。
    zsz
        23
    zsz  
       2017-04-30 13:59:24 +08:00 via iPhone
    @sagaxu 同意你的看法,楼主用默认的功能满足需求,暂时不需要考虑过复杂,系统一步步迭代就好
    wwqgtxx
        24
    wwqgtxx  
       2017-04-30 14:08:00 +08:00 via iPhone
    @zsz 而且实际上一般并不会遇到在同一个 session 下还跨语言吧,难道你 /a 和 /b 两个路径下还用了不同的后端来实现?
    wwqgtxx
        25
    wwqgtxx  
       2017-04-30 14:11:39 +08:00 via iPhone
    而且如果真的要实现跨后端 session 就单独用一个 cookie 来保存一个 session id,然后后端用 redis 或者 memcache 共享呗,不过要使用一种通用的序列化方式来保存 session 内容,比如 json 或者 yaml
    zsz
        26
    zsz  
       2017-04-30 14:21:31 +08:00 via iPhone
    @wwqgtxx 亲身参与过的几个系统都有这个问题,现实世界也比较难按单个团队的想法去整合,基本还是按照你说的后一种做法 cookie 保存 sid 对接的
    kaneg
        27
    kaneg  
       2017-04-30 15:54:58 +08:00 via iPhone
    以上几位差不多都说的很清楚了,Flask 的确是用 cookie 来保存 session 的,是比较奇特的一种方式,但不用担心安全问题,因为已经加密过了,但记得修改默认密钥。

    不过因为是 cookie 存储,所以有浏览器的大小限制,已经存储的对象还得能够序列化和反序列化。除此之外,如果存储太多,来回传输也影响效率。所以 Flask 的作者建议尽量不要往 session 里保存太多东西,不要把 session 当缓存用,而只应该保存关键的 key,比如用户 ID,name 等。
    node
        28
    node  
       2017-04-30 21:20:54 +08:00
    前面有几位回答得挺全面的,直接回答楼主的问题吧,如果不考虑可篡改性的问题,默认 session 和 request.cookies 没太大区别,但 flask 的 session 是个通用框架,建议的做法是把 session 换成存储在服务器端的实现,因为 cookies 请求来回都得带上,数据都带在里面流量浪费了
    ryd994
        29
    ryd994  
       2017-05-01 13:26:21 +08:00 via Android
    flask 这个 session 就是个脚手架,给你小规模和测试用起来方便而已
    想要换成基于服务器的 session 就是几行代码的事
    你现在全放 cookie 里的话,将来改服务端 session 就难了
    geek123
        30
    geek123  
       2018-03-07 11:53:38 +08:00
    推荐一个 flask 的入门教程给大家:
    [深入浅出 flask](url=http://xc.hubwiz.com/course/562427361bc20c980538e26f?affid=v2ex20180307)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1091 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:33 · PVG 07:33 · LAX 15:33 · JFK 18:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.