第十阶段 -- Flask框架05:【Flask高级01:cookie;session】

一. cookie

1. Cookie 的基本概念

  1. 什么是cookie:

​ 在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。

​ cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。

​ cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。

  1. cookie的有效期:

​ 服务器可以设置cookie的有效期,以后浏览器会自动的清除过期的cookie。

  1. cookie有域名的概念:

​ 只有访问同一个域名,才会把之前相同域名返回的cookie携带给服务器。也就是说,访问百度的时候,不会把新浪网站的cookie发送给百度。

  1. 画个图演示Cookie的工作过程

在这里插入图片描述

2.Flask 设置和删除 cookie

  1. 设置cookie:

    设置cookie是在Response的对象上设置。

    flask.Response对象有一个set_cookie方法,可以通过这个方法来设置cookie信息。key, value形式设置信息。

  2. 查看cookie信息

    在Chrome浏览器中查看cookie的方式:

​ * 方式01:借助于 开发调式工具进行查看

​ * 方式02:在Chrome的设置界面->高级设置->内容设置->所有cookie->找到当前域名下的cookie。

  1. 删除cookie:
    • 方式01:通过Response对象.delete_cookie,指定cookie的key,就可以删除cookie了。
    • 方式02:在客户端浏览器 人为的删除(清除浏览器浏览历史记录后,很多网站之前免密登录的都不好使了)
from flask import Flask,request,Response

app = Flask(__name__)

@app.route('/')
def hello_world():
    resp = Response("SXT")
    # 设置Cookie信息
    resp.set_cookie('username','momo')
    resp.set_cookie('pwd','123456')
    return resp

@app.route('/del/')
def delete_cookie():
    resp = Response("删除cookie")
    # 删除Cookie信息
    resp.delete_cookie('username')
    return resp

if __name__ == '__main__':
    app.run(debug=True)

3. Flask 设置 cookie 的过期时间

  • 设置cookie的有效期:
  1. 方式01max_age:以秒为单位,距离现在多少秒后cookie会过期

    方式02expires:为datetime类型。这个时间需要设置为格林尼治时间,相对北京时间来说 会自动+8小时

  2. 如果 max_ageexpires 都设置了,那么这时候以 max_age 为标准。

  3. 默认的过期时间:如果没有显示的指定过期时间,那么这个cookie将会在浏览器关闭后过期。

  • 注意:
  1. max_ageIE8 以下的浏览器是不支持的。

  2. expires虽然在新版的 HTTP 协议中是被废弃了,但是到目前为止,所有的浏览器都还是能够支持,所以如果想要兼容IE8以下的浏览器,那么应该使用 expires,否则可以使用 max_age。

  • 示例:
from flask import Flask,request,Response
from datetime import datetime,timedelta
app = Flask(__name__)
@app.route('/createCookie/')
def createCookie():
    resp = Response("服务器端通过Response对象创建Cookie信息  并返回给客户端  并保存在客户端")
    # 设置Cookie的有效期【存活时间】方式01 :max_age=以秒为单位【距离现在多少秒后cookie会过期】
    # resp.set_cookie('uname',"momo",max_age=1200)
    # 设置Cookie的有效期【存活时间】方式02 : expires= datetime类型。
    # 这个时间需要设置为格林尼治时间,相对北京时间来说 会自动+8小时
    # ex = datetime(year=2019, month=2, day=28, hour=0, minute=0, second=0)
    ex = datetime(year=2019, month=2, day=27, hour=16, minute=0, second=0)

    # resp.set_cookie('uname', "momo", expires=ex)
    ex2 =datetime.now() + timedelta(days=29,hours=16) # cookie的有效期为30天
    # 如果max_age和expires都设置了,那么这时候以max_age为标准
    # resp.set_cookie('pwd',"123456",max_age=300,expires=ex2)
    resp.set_cookie('pwd',"123456",expires=ex2)
    return resp

if __name__ == '__main__':
    app.run(debug=True)

4. Flask 设置文件有效域名

  • cookie默认是只能在主域名下使用。如果想要在子域名下使用,那么应该给 set_cookie 传递一个参数 domain='.momo.com' (注意momo前面要有“ . ”),这样其他子域名才能访问到这个cookie信息。

  • 例如:

from flask import Blueprint,request

bp = Blueprint('cms',__name__,subdomain='cms')

@bp.route('/')
def index():
    # request.args
    # request.form
    # request.files
    uname = request.cookies.get('uname')
    return uname or "没有获取到cookie"

windows 上的 hosts 文件如下:

在这里插入图片描述

from flask import Flask,Response,request
from datetime import datetime,timedelta
from cmsblueprint  import bp
app = Flask(__name__)

app.register_blueprint(bp)
app.config['SERVER_NAME'] = 'momo.com:5000'

@app.route('/createCookie/')
def createCookie():
    resp = Response("服务器端通过Response对象创建Cookie信息  并返回给客户端  并保存在客户端")
    ex = datetime(year=2019, month=2, day=27, hour=16, minute=0, second=0)
    ex2 =datetime.now() + timedelta(days=30,hours=16)
    resp.set_cookie('pwd',"123456",expires=ex2)

    # 给Cookie信息设置存活时间【有效域名---》子域名】
    resp.set_cookie('uname', "momo", expires=ex,domain=".momo.com")
    return resp

if __name__ == '__main__':
    app.run(debug=True)

6. 实例

  • 【25_cookie_demo.py】
from flask import Flask,Response
from datetime import datetime,timedelta
from cmsblueprint import bp
app = Flask(__name__)

app.register_blueprint(bp)
app.config['SERVER_NAME']="momo.com:5000"

# 02.查看cookie信息 [借助于开发调式工具进行查看]
@app.route('/')
def hello_world():
    return 'Hello World!'

@app.route('/createCookie/')
def createCookie():
    resp = Response('由服务器端创建Cookie信息;数据量是少量的;返回给客户端;并由客户端进行Cookie信息的保存')
    # 01.设置cookie(创建Cookie信息)
    # resp.set_cookie("uname","momo")
    # resp.set_cookie("pwd","123456")

    # 04. 设置cookie的有效期
    # 设置Cookie的有效期【存活时间】方式1 :max_age=以秒为单位【距离现在多少秒后cookie会过期】
    # resp.set_cookie('uname',"momo",max_age=60)  # 60秒免登录
    # resp.set_cookie('uname',"momo",max_age=1500)  # 1500秒免登录
    # 设置Cookie的有效期【存活时间】方式2 : expires= datetime类型。
    # 这个时间需要设置为格林尼治时间,相对北京时间来说 会自动+8小时
    # ex = datetime(year=2019, month=7, day=19, hour=0, minute=0, second=0)
    # ex = datetime(year=2019, month=7, day=10, hour=16, minute=0, second=0)
    # resp.set_cookie("uname","momo",expires=ex)

    # 如果max_age和expires都设置了,那么这时候以max_age为标准。
    # resp.set_cookie("uname","momo",max_age=1600,expires=ex)
    ex2=datetime.now() + timedelta(days=29,hours=16)  #代表存活时间为30天
    # 开发时实际写法
    resp.set_cookie("pwd", "123456")
    # resp.set_cookie("uname", "momo",expires=ex2)
    # 05.给Cookie信息设置存活时间  【有效域名---》子域名】
    resp.set_cookie("uname","lulu",expires=ex2,domain=".momo.com")
    return resp

@app.route('/deleteCookie/')
def deleteCookie():
    # 03.删除cookie
    resp = Response("我是用来在服务器端删除指定Cookie信息的")
    resp.delete_cookie("pwd")
    return resp

if __name__ == '__main__':
    app.run(debug=True)

from flask import Blueprint,request

bp = Blueprint('cms',__name__,subdomain='cms')

@bp.route('/')
def index():
    # request.args
    # request.form
    # request.files
    uname = request.cookies.get('uname')
    return uname or "没有获取到cookie"

二. session

1. session 基本概念

  1. 概念:

    ​ session和cookie的作用有点类似,都是为了存储用户相关的信息,都是为了解决http协议无状态的这个特点。不同的是,cookie信息是存储在客户端,而session信息是存储在服务器端。

    ​ 需要注意的是,不同的语言,不同的框架,有不同的实现。虽然底层的实现不完全一样,但目的都是让服务器端能方便的存储数据而产生的。

    ​ session的出现,是为了解决cookie存储数据不安全的问题的。

  2. session 的跟踪机制跟 cookie 有关:

  • Flask框架中,session的跟踪机制跟Cookie有关,这也就意味着脱离了Cookie,session就不好使了。
  • 因为session跟踪机制跟cookie有关,所以,要分服务器端和客户端分别起到什么功能来理解。
  1. 工作过程

    ​ 服务器端可以采用类似于mysql、redis等技术来存储session信息。原理是,客户端发送验证信息过来(比如用户名和密码),服务器验证成功后,把用户的相关信息存储到服务器端的session中(可想象为一个容器),再通过盐的机制,盐起到混淆原数据的作用(类似于加密),然后随机生成一个唯一的session_id,用来标识(用户名和密码)并存储到session中,之后再把这个session_id存储到cookie中返回给浏览器。浏览器以后再请求我们服务器的时候,就会把这个session_id通过Cookie技术自动的发送给服务器,服务器端再从cookie中提取session_id,然后从服务器的session容器中找到这个用户的相关信息。这样就可以达到安全识别用户的需求了。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。

  2. 服务器端功能

    1. 把用户的相关信息存储到服务器端的session中
    2. 通过盐的机制加密随机生成一个唯一的session_id,用来标识用户相关信息并将session_id也存入session中
    3. 把session作为cookie的key,session_id作为cookie的value创建cookie信息并返回给客户端
    4. 客户端发送第二次以后的请求时,获取cookie信息,与服务器端session容器中session_id对比,得出指定 用户信息。
  3. 客户端功能

    1. 通过cookie存储session加密后的session_id信息
    2. 以后浏览器再请求服务器的时候,就会自动的把cookie信息(包含session_id)发送给服务器
  4. 扩展面试题:

    若客户端禁用了浏览器的Cookie功能,session功能想继续保留,该咋整?给出你的实现思路(能代码实现最好)

2. Flask 操作 session

  1. 设置 session

    通过flask.session就可以操作session了。操作session就跟操作字典是一样的。

    session['uname']='momo'

  2. 获取session

    也是类似字典,

    session.get(key)。

  3. 删除session中的值

    也是类似字典。可以有2种方式删除session中的值。

​ * session.pop(key)。

​ * session.clear():删除session中所有的值。

  1. 设置session的有效期

    如果没有设置session的有效期。那么默认就是浏览器关闭后过期。

    如果设置session.permanent=True,那么就会默认在31天后过期。

    如果不想在31天后过期,按如下步骤操作

    1. session.permanent=True
    2. 可以设置app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hour=2)在两个小时后过期。
  2. 代码演示:

from flask import Flask,session,Response
import os
from datetime import timedelta
app = Flask(__name__)

# 00设置SECRET_KEY
app.config['SECRET_KEY'] = os.urandom(24)
# 05.设置session的有效期方式2【指session可以往后活多长时间】
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=2)

# 01.设置session
@app.route('/')
def  index():
    session['uname'] = 'momo'
    session['pwd'] = '123'
    # 底层
    # resp = Response()
    # resp.set_cookie('session')

    # 04.设置session的有效期方式1【持久化 31天】
    session.permanent = True
    # print(type(session))
    return 'Hello World!'

# 02.获取session
@app.route('/getSession/')
def getSession():
    uname = session.get('uname')
    pwd = session.get('pwd')
    print(pwd)
    return uname or '没有session'

# 03.删除session
@app.route('/deleteSession/')
def deleteSession():
    #删除指定的key的session
    # session.pop('uname')
    #删除session中的所有的key 【删除所有】
    session.clear()
    return '删除成功'

if __name__ == '__main__':
    app.run(debug=True)

  1. 示例
  • 26_session_demo.py
from flask import Flask,session,render_template,request
import os
from datetime import timedelta
app = Flask(__name__)

# 00设置SECRET_KEY
app.config['SECRET_KEY']=os.urandom(24)
# 05.设置session的有效期方式2【指session可以往后活多长时间】
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=2)  #设置session的存活时间是2小时
# 01.设置session
@app.route('/')
def index():
    # session['uname'] = 'momo'
    # session['pwd'] = '123'
    # 底层
    # resp = Response()
    # resp.set_cookie('session','session_id是一个唯一随机数')

    # 4.设置session的有效期方式1【持久化 31天】
    # session.permanent = True
    # print(type(session))
    return render_template("login.html")

# 02.获取session
@app.route('/getSession/')
def getSession():
    uname = session.get('uname')
    pwd = session.get('pwd')
    print(pwd)
    return uname or '没有session'

# 03.删除session
@app.route('/deleteSession/')
def deleteSession():
    # 删除指定的key的session
    # session.pop('uname')
    # 删除session中的所有的key 【删除所有】
    session.clear()
    return '删除成功'

# 06.session的使用场景:基于session实现访问一个项目的n个页面时  依然知道该用户是谁
@app.route('/login/',methods=['get','post'])
def login():
    # 获取用户名好密码
    uname = request.form['uname']
    pwd = request.form['pwd']
    # 去数据库做数据验证   验证OK

    # 把用户名存入session中
    session['user'] = uname
    session.permanent=True
    return render_template('index.html')

@app.route('/moives/')
def moives():
    return render_template('movies.html')

if __name__ == '__main__':
    app.run(debug=True)

  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>这是系统首页</h2>
    <p>当前用户:{{ session.get('user')}}</p>
   <a href="/moives/">视频模块</a>
</body>
</html>
  • login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
     <form action="/login/" method="post">
         用户名:<input type="text" name="uname"><br>
         密码:<input type="password" name="pwd"><br>
         <input type="submit" value="登录">
     </form>
</body>
</html>
  • movies.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
        <h2>这是视频模块首页</h2>
        <p>当前用户:{{ session.get('user')}}</p>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值