cookie和session
cookie 和 session 是 Web 开发中经常被使用的技术,因为 HTTP 请求是无状态的,也就是说每次请求间是相互独立的,如第一次请求成功后,接着发起第二次请求时,服务器依然不知道是谁发起的请求。而 cookie 和 session 就是为了解决这个问题而出现的。
关于cookie和session的介绍
cookie
cookie 的出现,就是为了解决 HTTP 请求无状态的问题。如果想要识别用户,可以在用户第一次请求后,在服务器端生成一段能识别用户的数据,存放到 cookie 中,然后返回给浏览器,浏览器会自动存储 cookie 数据。当该用户对同一网站发送第二次请求时,浏览器会自动把上次请求获取的 cookie 发送给服务器,服务器通过浏览器发送的 cookie 就能知道是哪个用户了。cookie 存储的数据量有限,不同的浏览器存储容量也不同,但一般不超过 4KB,因此 cookie 只适合存储少量的数据。
session
session 与 cookie 的作用类似,都是为了存储用户相关的信息。不同的是,cookie 是存储在浏览器中,而 session 是一个概念,一个服务器存储授权信息的解决方案,不同的服务器,不同的框架,不同的编程语言都有不同的实现。Web 开发发展至今,session 的使用已经有了非常成熟的解决方案。在如今的市场环境中,一般 session 的存储有以下两种方式。
-
存储在服务器端:服务器在存储 session 时,首先生成 session_id,然后把 session_id 和具体的 session 数据进行关联,并存储在服务器端,如数据库,或者是缓存中(如 Memcached、Redis)。接着把 session_id 存放到 cookie 中返回给浏览器,下次用户访问时,因为 cookie 会自动携带,所以服务器可以从 cookie 中获取 session_id,然后再从数据库或者缓存中获取具体的 session 数据。把 session 存储在服务器的好处是更加安全,不容易被窃取,坏处是会占用服务器资源,但是现在硬件条件已经非常先进了,存储一些 session 信息还是绰绰有余的。
-
存储在客户端:在存储 session 时,先将 session 进行加密,然后直接存储在 cookie 中返回给浏览器,下次用户访问时,则从 cookie 中获取 session 数据。Flask 默认就是采用这种方式,当然也可以替换为存储在服务器端的方式。
Flask中使用cookie和session
Flask中操作cookie
在 Flask 中操作 cookie 是通过响应对象实现的,如 Response 或者其子类。Response 及其子类有一个 set_cookie 方法可以设置 cookie,set_cookie 的参数如下。
-
key:设置 cookie 的 key。
-
value:设置 cookie 的 value
-
ax_age:设置 cookie 距离现在多少秒后过期。
-
expires:设置 cookie 具体的过期时间,类型为 datetime 或者时间戳。
-
domain:设置 cookie 在哪个域名中有效。一般是设置子域名也能共享 cookie,如 cms.example.com。
-
path:设置 cookie 在当前域名下的哪些 path 下有效,默认是在所有 path 下都有效。
在 Flask 中设置和获取 cookie 的示例代码如下。
from flask import make_response, request
# 设置cookie
@app.route('/')
def index():
resp = make_response(render_template(...))
resp.set_cookie('username', 'the username')
return resp
# 获取cookie
@app.route('/user')
def user():
username = request.cookies.get('username')
return username
上述代码中,首先通过 make_response 获取一个 Response 对象,然后调用 set_cookie 方法设置 cookie 数据,最后在 user 视图函数中,通过 request.cookies.get 方法来获取 cookie 数据。
Flask中操作session
在 Flask 中操作 session 是通过全局对象 flask.session 实现的,flask.session 是一个类字典形式,因此对 session 做增删改查操作时都可以使用字典相关的方法,示例代码如下。
from flask import session
# 设置session
@app.route('/')
def index():
session["username"] = "the username"
return "Session set!"
# 获取session
@app.route('/user')
def user():
username = session['username']
return f"Username from session: {username}"
另外,使用 session 的前提是,在 app.config 中配置好 SECRET_KEY。