1、cookie

1、cookie介绍

在网站中,http请求是无状态的(cookie就是记录用户信息,让服务器能够知道登录的用户是谁)。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
image.png

2、cookie的生成与查看

cookie的生成——存储在response中
生成一个cookies:
代码部分:

  1. # 因为cookie是生成在Response中的所以导入Response类
  2. from flask import Flask, Response
  3. app = Flask(__name__)
  4. @app.route("/")
  5. def home():
  6. res = Response("这是一个关于cookie的测试")
  7. # 调用set_cookie方法
  8. res.set_cookie("name", "ABC") # 设置max_age=1000参数,改变过期时间
  9. return res
  10. if __name__ == '__main__':
  11. app.run(debug=True)

关于set_cookie方法的相关说明:

  1. def set_cookie(
  2. self,
  3. key, # 对应上文的name
  4. value="", # 对应上文的ABC
  5. max_age=None, # cookie过期时间,单位是秒
  6. expires=None, # 同样是过期时间,但是写的是datetime对象或者是UNIX时间戳
  7. path="/", # 设置路径
  8. domain=None, # 设置子域名
  9. secure=False, # 如果'True',则cookie只能通过HTTPS获得
  10. httponly=False, # 如果为False,禁止JavaScript访问cookie
  11. samesite=None, # 限制cookie的范围
  12. ):

查看生成的cookie
image.png

2、session

session介绍-一般保存在服务器中,但是flask将其进行加密保存在cookie保存在浏览器中
session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,session是一个思路、一个概念、一个服务器存储授权信息的解决方案,不同的服务器,不同的框架,不同的语言有不同的实现。虽然实现不一样,但是他们的目的都是服务器为了方便存储数据的。session的出现,是为了解决cookie存储数据不安全的问题的。
image.png
不过大多数时候session不存在数据库中,而是存放在缓存中

3、cookie和session结合使用

web开发发展至今,cookie和session的使用已经出现了一些非常成熟的方案。在如今的市场或者企业里,一般有两种存储方式:
1、存储在服务端:通过cookie存储一个session_id,然后具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。
2、将session数据加密,然后存储在cookie中。这种专业术语叫做client side session。flask采用的就是这种方式,但是也可以替换成其他形式。

4、flask中使用cookie和session

1、写一个session小例子

  1. import os
  2. from flask import Flask, session
  3. app = Flask(__name__)
  4. # 由于需要对session进行加密,所以要对SECRET_KEY进行配置
  5. # 但是如果对其进行写死(ANFJNE1425)会存在一定的风险
  6. # app.config['SECRET_KEY'] = "ANFJNE1425"
  7. # 这里通过os.urandom方法生成随机的字符串,可以有效的避免这个问题
  8. app.config['SECRET_KEY'] = os.urandom(12)
  9. @app.route("/")
  10. def home():
  11. # 添加数据
  12. session['name'] = "gongzhujun"
  13. return "首页"
  14. if __name__ == '__main__':
  15. app.run(debug=True)

代码解读:
导入session,session类似于字典

  1. from flask import session

配置SECRET_KEY, 使用有os.urandom生成的随机字符串,更加的安全

  1. app.config['SECRET_KEY'] = os.urandom(12)

添加数据,可以添加多个

  1. session['name'] = "gongzhujun"
  2. # session['user_id'] = "17258"

2、session的持久化

在添加session.permanent = True的情况下,session的有效时间默认为一个月(不添加的话就是退出即失效)

  1. import os
  2. from flask import Flask, session
  3. app = Flask(__name__)
  4. app.config['SECRET_KEY'] = os.urandom(12)
  5. @app.route("/")
  6. def home():
  7. session['name'] = "gongzhujun"
  8. session['password'] = "123644"
  9. return "首页"
  10. if __name__ == '__main__':
  11. app.run(debug=True)

如果不想要默认的时间,可以通过配置config文件改变默认的持久化时间(需要导入timedelta)

  1. import os
  2. from flask import Flask, session
  3. from datetime import timedelta
  4. app = Flask(__name__)
  5. app.config['SECRET_KEY'] = os.urandom(12)
  6. # 添加需要持续的时间
  7. app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=2)
  8. @app.route("/")
  9. def home():
  10. session['name'] = "gongzhujun"
  11. session['password'] = "123644"
  12. # 持久化,默认为一个月
  13. session.permanent = True
  14. return "首页"
  15. if __name__ == '__main__':
  16. app.run(debug=True)

页面显示:
image.png

5、在其他页面获取session内容

代码部分:

  1. import os
  2. from flask import Flask, session
  3. from datetime import timedelta
  4. app = Flask(__name__)
  5. app.config['SECRET_KEY'] = os.urandom(12)
  6. app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=2)
  7. @app.route("/login/")
  8. def login():
  9. session['name'] = "gongzhujun"
  10. session['password'] = "123644"
  11. session.permanent = True
  12. return "登录页"
  13. @app.route("/")
  14. def home():
  15. # 通过get方法获取对应的值,可以通过session['name']进行获取,但是如果没有对应的key值会报错
  16. name = session.get('name')
  17. print(name)
  18. return "首页"
  19. if __name__ == '__main__':
  20. app.run(debug=True)

注意点:
首先要对session进行上传,其他页面才能获取到对应的值
image.png
第一次没有获取到对应的值,是因为没有通过login上传session值,在上传session后就正常了

6、删除session中的某个值或者对其进行清空

1、删除session中的某个值(.pop())

  1. @app.route('/logout/')
  2. def logout():
  3. # 弹出某个键值
  4. session.pop("name")
  5. return "退出登录"

2、清空session(.clear())

  1. @app.route('/logout/')
  2. def logout():
  3. # 弹出某个键值
  4. session.clear()
  5. return "退出登录"