文章目录
一. cookie
1. Cookie 的基本概念
- 什么是cookie:
在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。
cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。
cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
- cookie的有效期:
服务器可以设置cookie的有效期,以后浏览器会自动的清除过期的cookie。
- cookie有域名的概念:
只有访问同一个域名,才会把之前相同域名返回的cookie携带给服务器。也就是说,访问百度的时候,不会把新浪网站的cookie发送给百度。
- 画个图演示Cookie的工作过程
2.Flask 设置和删除 cookie
-
设置cookie:
设置cookie是在Response的对象上设置。
flask.Response
对象有一个set_cookie
方法,可以通过这个方法来设置cookie
信息。key, value形式设置信息。 -
查看cookie信息
在Chrome浏览器中查看cookie的方式:
* 方式01:借助于 开发调式工具进行查看
* 方式02:在Chrome的设置界面->高级设置->内容设置->所有cookie->找到当前域名下的cookie。
- 删除cookie:
- 方式01:通过
Response对象.delete_cookie
,指定cookie的key,就可以删除cookie了。 - 方式02:在客户端浏览器 人为的删除(清除浏览器浏览历史记录后,很多网站之前免密登录的都不好使了)
- 方式01:通过
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的有效期:
-
方式01 –
max_age
:以秒为单位,距离现在多少秒后cookie会过期方式02 –
expires
:为datetime类型。这个时间需要设置为格林尼治时间,相对北京时间来说 会自动+8小时 -
如果
max_age
和expires
都设置了,那么这时候以max_age
为标准。 -
默认的过期时间:如果没有显示的指定过期时间,那么这个cookie将会在浏览器关闭后过期。
- 注意:
-
max_age
在 IE8 以下的浏览器是不支持的。 -
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 基本概念
-
概念:
session和cookie的作用有点类似,都是为了存储用户相关的信息,都是为了解决http协议无状态的这个特点。不同的是,cookie信息是存储在客户端,而session信息是存储在服务器端。
需要注意的是,不同的语言,不同的框架,有不同的实现。虽然底层的实现不完全一样,但目的都是让服务器端能方便的存储数据而产生的。
session的出现,是为了解决cookie存储数据不安全的问题的。
-
session 的跟踪机制跟 cookie 有关:
- Flask框架中,session的跟踪机制跟Cookie有关,这也就意味着脱离了Cookie,session就不好使了。
- 因为session跟踪机制跟cookie有关,所以,要分服务器端和客户端分别起到什么功能来理解。
-
工作过程:
服务器端可以采用类似于mysql、redis等技术来存储session信息。原理是,客户端发送验证信息过来(比如用户名和密码),服务器验证成功后,把用户的相关信息存储到服务器端的session中(可想象为一个容器),再通过盐的机制,盐起到混淆原数据的作用(类似于加密),然后随机生成一个唯一的session_id,用来标识(用户名和密码)并存储到session中,之后再把这个session_id存储到cookie中返回给浏览器。浏览器以后再请求我们服务器的时候,就会把这个session_id通过Cookie技术自动的发送给服务器,服务器端再从cookie中提取session_id,然后从服务器的session容器中找到这个用户的相关信息。这样就可以达到安全识别用户的需求了。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。
-
服务器端功能:
- 把用户的相关信息存储到服务器端的session中
- 通过盐的机制加密随机生成一个唯一的session_id,用来标识用户相关信息并将session_id也存入session中
- 把session作为cookie的key,session_id作为cookie的value创建cookie信息并返回给客户端
- 客户端发送第二次以后的请求时,获取cookie信息,与服务器端session容器中session_id对比,得出指定 用户信息。
-
客户端功能:
- 通过cookie存储session加密后的session_id信息
- 以后浏览器再请求服务器的时候,就会自动的把cookie信息(包含session_id)发送给服务器
-
扩展面试题:
若客户端禁用了浏览器的Cookie功能,session功能想继续保留,该咋整?给出你的实现思路(能代码实现最好)
2. Flask 操作 session
-
设置 session:
通过
flask.session
就可以操作session了。操作session
就跟操作字典是一样的。session['uname']='momo'
。 -
获取session:
也是类似字典,
session.get(key)。
-
删除session中的值:
也是类似字典。可以有2种方式删除session中的值。
* session.pop(key)。
* session.clear():删除session中所有的值。
-
设置session的有效期:
如果没有设置session的有效期。那么默认就是浏览器关闭后过期。
如果设置session.permanent=True,那么就会默认在31天后过期。
如果不想在31天后过期,按如下步骤操作
- session.permanent=True
- 可以设置
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hour=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)
- 示例
- 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>