Cookie和Session的概念
Cookie
在网站中,http 请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。
cookie
的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会把上次请求存储的cookie 数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前是哪个用户了。 cookie 存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4kb
。 因此使用 cookie 只能存储一些小量的数据。
Session
session
和 cookie 的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie 是存储在本地浏览器,而 session 存储在服务器。 存储在服务器的数据会更加安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,存储一些 session 信息还是绰绰有余的。
cookie 和 session 结合使用:cookie 和 session 的使用已经出现了一些非常成熟的方案。一般有两种存储方式
- 存储在服务端:通过 cookie 存储一个 session_id,然后具体的数据则保存在 session 中。如果用户已经登录,则服务器会在 cookie 中保存一个 session_id,下次再请求的时候,会把该 session_id 携带上,服务器根据session_id 在 sesson 库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做 server side session.
- 将 session 数据加密,然后存储在cookie中。这种专业术语叫做 client side session。Flask采用的就是这种方式,但是也可以替换成其它方式。
Cookie的使用
在 Flask 中利用
make_response()
函数创建出来的 Response 对象就可以对 Cookie 进行相关操作
Response对象的 set_cookie()
方法参数详情
def set_cookie(
self,
key,
value="",
max_age=None,
expires=None,
path="/",
domain=None,
secure=False,
httponly=False,
samesite=None,
):
常用参数说明
- key cookie的键
- value cookie的值
- max_age 设置 cookie 存储多久 单位秒,默认则是一次浏览器会话,关闭浏览器就没有了。
- expires 设置 cookie 过期日期,必须是一个
datetime
对象类型或者UNIX
时间戳 - path 限制cookie到一个给定的路径,默认情况下它将属于整个域名下
如果 max_age
和 expires
都设置了,则以 max_age
参为准
若没有设置过期时间,则默认为浏览会话结束,即关闭浏览器(是关闭浏览器,不是关闭页面)时过期
Cookie的设置与获取
代码语言:javascript复制from flask import Flask, make_response, request
app = Flask(__name__)
# 设置Cookie
@app.route("/set_cookie")
def set_cookie():
resp = make_response('success')
resp.set_cookie("name", "hui")
resp.set_cookie("age", "21")
return resp
# 获取Cookie
@app.route("/get_cookie")
def get_cookie():
name = request.cookies.get("name")
age = request.cookies.get("age")
resp = f"name={name}, age={age}"
return resp
if __name__ == "__main__":
app.run()
使用 make_response()
函数来创建 Response
响应对象,然后使用 set_cookie()
方法设置cookie
数据
获取 Cookie
则是用 request.cookies.get()
设置过 Cookie
了,下次请求浏览器会自动携带 Cookie
信息。因此在request.cookies
获取cookie
信息
查看Cookie过期时间
Cookie设置过期时间
代码语言:javascript复制from datetime import datetime, timedelta
from flask import Flask, make_response, request
app = Flask(__name__)
@app.route("/set_expires")
def set_cookie_expires():
resp = make_response("设置cookie过期时间")
# 设置1分钟后过期
resp.set_cookie("sex", "male", max_age=60)
# 设置一天后过期
expires_date = datetime.now() timedelta(days=1, hours=-8)
resp.set_cookie("city", "GanZhou", expires=expires_date)
return resp
如果使用
expires
,浏览器则会默认使用 格林尼治 时间,即在设置的时间自动 8小时,因此我们在设置过期时间时需要减掉这8小时才符号我们的预期。datetime
对象在进行时间间隔运算不能直接加减要借助timedelta
删除Cookie
代码语言:javascript复制from flask import Flask, make_response
app = Flask(__name__)
@app.route("/del_cookie")
def del_cookie():
resp = make_response("del cookie")
resp.delete_cookie("name")
return resp
其删除 cookie
其实就是把过期设置成 max_age=0, expires=0
看看 Flask
源码,就可得知
def delete_cookie(self, key, path="/", domain=None):
"""Delete a cookie. Fails silently if key doesn't exist.
:param key: the key (name) of the cookie to be deleted.
:param path: if the cookie that should be deleted was limited to a
path, the path has to be defined here.
:param domain: if the cookie that should be deleted was limited to a
domain, that domain has to be defined here.
"""
self.set_cookie(key, expires=0, max_age=0, path=path, domain=domain)
Session的使用
Session的设置与获取
代码语言:javascript复制"""
Author: Hui
Desc: { Flask session的使用 }
"""
from flask import Flask, session
app = Flask(__name__)
app.config["SECRET_KEY"] = "it hui"
# flask默认吧session保存在cookie中
@app.route("/index")
def index():
name = session.get("name")
return "hello {}".format(name)
@app.route("/login")
def login():
session["name"] = "hui"
return "set session name"
if __name__ == "__main__":
app.run()
设置session时记得添加密钥配置
代码语言:javascript复制app.SECRECT_KEY = "it hui"
如不设置则会报如下错误
代码语言:javascript复制RuntimeError: The session is unavailable because no secret key was set. Set the secret_key on the application to something unique and secret.
测试上面的程序,先访问 127.0.0.1:5000/index
然后访问 127.0.0.1:5000/login
设置 session
然后再访问 127.0.0.1:5000/index
看看
Flask
默认把 session
保存在 cookie
中
当前设置了一个 key
为 name
的,值为 hui
的 session
信息,来查看浏览器 Cookie
信息
只是 session
信息内容被加密了,因为要用到 SECRET_KEY
信息来加密 session
信息, 所以设置 session
时要设置密钥 SECRET_KEY
。因为 Flask 的 session 信息存储在本地 cookie 中,是可以被篡改的,为了保证安全性,一旦被修改,Flask 则认为这是一个无效的 session 信息。
Session设置过期时间
Flask的
session
默认过期时为会话结束,如果开启会话过期时间(session.permanent=True)
,默认过期时间为 一个月,可以通过permanent_session_lifetime
Flask的配置信息来设置 session 的过期时间
从Flask源码就可得知
代码语言:javascript复制#: This attribute can also be configured from the config with the
#: ``PERMANENT_SESSION_LIFETIME`` configuration key. Defaults to
#: ``timedelta(days=31)``
permanent_session_lifetime = ConfigAttribute(
"PERMANENT_SESSION_LIFETIME", get_converter=_make_timedelta
)
设置过期时间使用 timedelta
对象
设置了 session.permanent = True
"""
Author: Hui
Desc: { Flask session的使用 }
"""
from datetime import timedelta
from flask import Flask, session
app = Flask(__name__)
app.config["SECRET_KEY"] = "it hui"
# 设置session过期时间
app.permanent_session_lifetime = timedelta(seconds=60)
# flask默认把session保存在cookie中
@app.route("/index")
def index():
name = session.get("name")
age = session.get("age")
return f"name={name}, age={age}"
@app.route("/age")
def set_session():
session["age"] = 21
return "set session age"
@app.route("/login")
def login():
session["name"] = "hui"
session.permanent = True
return "set session name"
if __name__ == "__main__":
app.run()
指定 session
过期时间为1分钟
app.permanent_session_lifetime = timedelta(seconds=60)
删除session
代码语言:javascript复制@app.route("del_session")
def del_session():
session.pop("name")
# session.clear() # 删除session所有信息
return "del session name"
源代码
源代码已上传到 Gitee
HuiDBK/FlaskBasic - 码云 - 开源中国 (gitee.com),欢迎大家来访。