Cookie 与 Session 简单了解

Cookie:  #存储大小受限,储存在客户端,有安全隐患

Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、
Netscape、Firefox、Opera等都支持Cookie。由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?
就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。 Session: #来完善Cookie Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,
服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了,
实质上session就是保存在服务器端的键值对。

Falsk 中 Session 的保管机制

交由客户端保管机制  实现过程
1.开启并设置 Session - session["user"] = 123
2.session 序列化字符串
3.通过 secret_key密钥 进行加密
4.通过 Cookie 返回客户端 接收Session
1.通过客户端 Cookie 获取 session
2.通过 secret_key密钥 进行解密
3.反序列化 字典
4.得到 session 优点:不占用服务器资源
缺点:保存在客户端,安全性相对较差 #一般我们都会使用三方组件提供的session模块,来解决flask session的安全问题,如 Flask-Session这个组件就可以帮我们解决问题.

相关的配置

Flask 中的 Session
- from flask import session
- 使用session的前提是在 application 中加入 secret_key 如:app.secret_key = "!@#$%^&*()" #Session 相关配置 想要配置生效必须在代码中重新配置 重启后生效
"SECRET_KEY": None, # 通用密钥
# 设置方法 app.secret_key = "!@#$%^&*()"(编码方便) 或 app.config['SECRET_KEY'] = "!@#$%^&*()"(效率高) session.pop('username') #删除session中的username对应的键和值
session.clear() #删除所有session "SESSION_COOKIE_NAME": "session",
# 设置session 在Cookie Session名称 app.session_cookie_name = 'session' "SESSION_COOKIE_HTTPONLY": True,
# 是否只在HTTP请求下开启 session ############################### 其他配置 ############################### {
'DEBUG': False,
# 是否开启Debug模式 开发环境 log级别低 重启代码错误透传 'TESTING': False,
# 是否开启测试模式 测试环境 log级别较高 'PROPAGATE_EXCEPTIONS': None,
# 异常传播(是否在控制台打印LOG) 当Debug或者testing开启后,自动为True 'PRESERVE_CONTEXT_ON_EXCEPTION': None,
# 一两句话说不清楚,一般不用它 'SECRET_KEY': None,
# 开启Session序列化,在启用Session的时候,一定要有它 'PERMANENT_SESSION_LIFETIME': 31,
# Session的生命周期(秒)默认31秒 'USE_X_SENDFILE': False,
# 是否弃用 x_sendfile 'LOGGER_NAME': None,
# 日志记录器的名称 'LOGGER_HANDLER_POLICY': 'always', 'SERVER_NAME': None, # 服务访问域名 'APPLICATION_ROOT': None, # 项目的完整路径 'SESSION_COOKIE_NAME': 'session', # 在cookies中存放session加密字符串的名字 'SESSION_COOKIE_DOMAIN': None, # 在哪个域名下会产生session记录在cookies中 'SESSION_COOKIE_PATH': None, # cookies的路径 'SESSION_COOKIE_HTTPONLY': True, # 控制 cookie 是否应被设置 httponly 的标志, 'SESSION_COOKIE_SECURE': False, # 控制 cookie 是否应被设置安全标志 'SESSION_REFRESH_EACH_REQUEST': True, # 这个标志控制永久会话如何刷新 'MAX_CONTENT_LENGTH': None,
# 如果设置为字节数, Flask 会拒绝内容长度大于此值的请求进入,并返回一个 413 状态码 'SEND_FILE_MAX_AGE_DEFAULT': 12, # hours 默认缓存控制的最大期限 'TRAP_BAD_REQUEST_ERRORS': False,
# 如果这个值被设置为 True ,Flask不会执行 HTTP 异常的错误处理,而是像对待其它异常一样,
# 通过异常栈让它冒泡地抛出。这对于需要找出 HTTP 异常源头的可怕调试情形是有用的。 'TRAP_HTTP_EXCEPTIONS': False,
# Werkzeug 处理请求中的特定数据的内部数据结构会抛出同样也是“错误的请求”异常的特殊的 key errors 。
# 同样地,为了保持一致,许多操作可以显式地抛出 BadRequest 异常。
# 因为在调试中,你希望准确地找出异常的原因,这个设置用于在这些情形下调试。
# 如果这个值被设置为 True ,你只会得到常规的回溯。 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', # 生成URL的时候如果没有可用的 URL 模式话将使用这个值 'JSON_AS_ASCII': True,
# 默认情况下 Flask 使用 ascii 编码来序列化对象。如果这个值被设置为 False ,
# Flask不会将其编码为 ASCII,并且按原样输出,返回它的 unicode 字符串。
# 比如 jsonfiy 会自动地采用 utf-8 来编码它然后才进行传输。 'JSON_SORT_KEYS': True,
#默认情况下 Flask 按照 JSON 对象的键的顺序来序来序列化它。
# 这样做是为了确保键的顺序不会受到字典的哈希种子的影响,从而返回的值每次都是一致的,不会造成无用的额外 HTTP 缓存。
# 你可以通过修改这个配置的值来覆盖默认的操作。但这是不被推荐的做法因为这个默认的行为可能会给你在性能的代价上带来改善。 'JSONIFY_PRETTYPRINT_REGULAR': True,
'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None,
}

使用 Flask-Session 三方组件

安装

#flask_session是flask框架实现session功能的一个插件,用来替代flask自带的session实现机制。

#安装
pip3 install flask-session #Flask-Session 支持 session保存到多个地方如:
- redis #存放在内网使用,不要存放在公网
- memcached
- filesystem
- mongodb
- sqlalchmey #存放在redis实例
import redis
from flask import Flask, session
from flask_session import Session app = Flask(__name__)
app.debug = True
app.secret_key = 'xxxx' app.config['SESSION_TYPE'] = 'redis' # session类型为redis
app.config['SESSION_PERMANENT'] = False # 如果设置为True,则关闭浏览器session就失效。
app.config['SESSION_USE_SIGNER'] = False # 是否对发送到浏览器上session的cookie值进行加密
app.config['SESSION_KEY_PREFIX'] = 'session:' # 保存到session中的值的前缀
app.config['SESSION_REDIS'] = redis.Redis(host='127.0.0.1', port='6379', password='123123') # 用于连接redis的配置 Session(app) @app.route('/index')
def index():
session['k1'] = 'v1'
return 'xx' if __name__ == '__main__':
app.run()

Flask-Session文件目录

################################  代码  ################################
# __init__.py Session配置代码
from flask import Flask,request,session
from flask_session import Session
from redis import Redis from app01.views.user import user_bp def create_app():
app = Flask(__name__) app.config["DEBUG"] = True
app.config["SESSION_TYPE"] = "redis"
app.config["SESSION_REDIS"] = Redis(host="127.0.0.1",port=6379,db=15) # app.session_interface = SecureCookieSessionInterface() # 原生 Session # 在Config之后 # 三方组件存活的空间
Session(app) #完成flask_session 对原生 Session的替换 # 在蓝图导入之前
app.register_blueprint(user_bp) return app # app01.py 蓝图代码
from flask import Blueprint # 蓝图是Flask实例,不可被run
user = Blueprint("user",__name__,url_prefix="/user") # Blueprint name 不能再同一个Flask实例中重复 @user.route("/reg")
def reg():
return "user注册成功" @user.route("/login")
def login():
return "user登录成功"

基础练习题

需求

使用以下数据制作学生详情页面
STUDENT_DICT = {
1: {'name': '钢蛋', 'age': 17, 'gender': '不详'},
2: {'name': '铁蛋', 'age': 19, 'gender': '男'},
3: {'name': '丫蛋', 'age': 18, 'gender': '女'},
} 要求:
1.编写登录页面 登录成功跳转到 学生概况页面
2.学生概况页面 只显示学生的 ID name 详细信息需点击后访问 学生详情页面页面查看
3.学生详情页面 显示这个学生的所有信息ID name age gender
4.基于Session编写登录验证装饰器 未登录状态只能访问 登录页面 登录成功后才可以访问 学生概况页面 与 学生详情页面

参考答案 (python代码)

from flask import Flask, request, render_template, redirect, session

STUDENT_DICT = {
1: {'name': '钢蛋', 'age': 17, 'gender': '不详'},
2: {'name': '铁蛋', 'age': 19, 'gender': '男'},
3: {'name': '丫蛋', 'age': 18, 'gender': '女'},
} app = Flask(__name__, template_folder='templates')#实例化一个Flask类,指定模板存放位置
app.secret_key = "!@#$%^&*()" # 密钥(对session进行加密)
app.debug = True # 开启Debug模式 修改代码自动重启项目 def check(func): # 装饰器 检测用户是否登录 利用session中的user的值做判断
def inner(*args, **kwargs):
if session.get('user') == 'gkf':
ret = func(*args, **kwargs)
return ret
else:
return redirect('/login') return inner @app.route('/login', methods=['POST', 'GET'], endpoint='login')#指定路由与接受请求方式,设置endpoint
def login():
if request.method == 'GET':
return render_template('login.html') #如果是get请求返回一个login.html if request.method == 'POST': #如果是post请求,把request.form中页面输入的值取出
username = request.form.get('username').lower()
password = request.form.get('password')
if username == 'gkf' and password == '123':#如果账户密码正确,设置 session["user"] = username
session["user"] = username
return redirect('/brief_introduction') #重定向到brief_introduction
else:
return '账号或密码错误' #如果账户密码不对,抛出错误提示 #设置endpoint='brief_introduction'让其与其他的视图函数不冲突,才能正常使用装饰器
@app.route('/brief_introduction', methods=('GET',), endpoint='brief_introduction')
@check #装饰器 必需添加在@app.route()下,不然会导致,使用装饰器导致@app.route()不被识别,报错
def brief_introduction():
return render_template('brief_introduction.html', st_obj=STUDENT_DICT)#返回brief_introduction.html 并传入STUDENT_DICT字典 调用名字为st_obj @app.route('/detailed', methods=('GET',), endpoint='detailed')
@check
def detailed(): #取出前端页面返回的url携带的学生编号, 并把它传给模板detailed.html 进行渲染
s_id = request.args.get('id') #对url携带参数做效验,确保返回的学生编号正确
if not s_id:
return "查询错误请重试"
if not s_id.isdecimal():
return "查询错误请重试"
s_id = int(s_id)
num = STUDENT_DICT.get(s_id,'')
if not num:
return "查询错误请重试"
else:
return render_template('detailed.html', id=s_id, st_obj=STUDENT_DICT) if __name__ == '__main__':
app.run()

参考答案 (html代码)

<!--templates 下 login.html 代码-->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>登录</title>
</head>
<body>
<h1>用户登录</h1>
<form action="" method="post" enctype="multipart/form-data">
<p>用户名: <input type="text" name="username"></p>
<p>密码: <input type="password" name="password"></p>
<input type="submit" value="登录">
</form>
</body>
</html> <!--templates 下 brief_introduction.html 代码-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生信息简介</title>
</head>
<body>
<h1>学生信息简介</h1>
<table border="1px">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for foo in st_obj %}
<tr>
<td>{{ foo }}</td>
<td>{{ st_obj[foo].name }}</td>
<!--把学生对应的编号添加到detailed的url上-->
<td><a href="http://127.0.0.1:5000/detailed?id={{ foo }}">点击查看详情<a></td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html> <!--templates 下 detailed.html 代码-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学生详细信息</title>
</head>
<body>
<h1>学生详细信息</h1>
<table border="1px">
<thead>
<tr>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ id }}</td>
<td>{{ st_obj[id].name }}</td>
<td>{{ st_obj[id].age }}</td>
{% if st_obj[id].gender=='不详' %}<!--判断对不正常的性别,修改显示结果-->
<td>男</td>
{% else %}
<td>{{ st_obj[id].gender }}</td>
{% endif %}
</tr>
</tbody>
</table>
</body>
</html>
作 者:郭楷丰
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角 推荐一下。您的鼓励是博主的最大动力!
自 勉:生活,需要追求;梦想,需要坚持;生命,需要珍惜;但人生的路上,更需要坚强。带着感恩的心启程,学会爱,爱父母,爱自己,爱朋友,爱他人。

Falsk框架 Session 与 Flask-Session的更多相关文章

  1. 初识Flask框架,以及Flask中的模板语言jinjia2和Flask内置的Session

    一.web框架的对比 首先我们先来看下比较火的web框架 1.Django: 优点:大而全,所有组件都是组织内部开发高度定制化,教科书级别的框架 缺点:大到浪费资源,请求的时候需要的资源较高 2.Fl ...

  2. flask框架基本使用(3)(session与cookies)

    #转载请留言联系 flask 框架基本使用(1):https://www.cnblogs.com/chichung/p/9756935.html flask 框架基本使用(2):https://www ...

  3. Flask框架(五) —— session源码分析

    Flask框架(五) —— session源码分析 目录 session源码分析 1.请求来了,执行__call__方法 2.__call__方法 3.调用__call__方法 3.1.ctx = s ...

  4. Flask框架【七】—session组件详解

    一.flask session简介 flask中session组件可分为内置的session组件还有第三方flask-session组件,内置的session组件缺点: 功能单一 session是保存 ...

  5. flask 状态保持session和上下文session的区别

    问题场景: 在falsk项目中导入了两个session:    首先,配置文件config.py文件中 有个 flask_session扩展导入了Session  ( from flask_sessi ...

  6. flask-admin章节四:flask session的使用

    1. 关于session flask session可能很多人根本都没有使用过,倒是cookie大家可能使用得比较多.flask cookie使用起来比较简单,就两个函数,读取和设置. 具体使用方式如 ...

  7. falsk 与 django cookie和session存、取、删的区别

    falsk cookie的存取删需导入from flask import Flask,make_response,request# 存COOKIE的方法@app.route('/setcookie') ...

  8. flask session,蓝图,装饰器,路由和对象配置

    1.Flask 中的路由   *endpoint - url_for 反向地址  *endpoint 默认是视图函数名  *methods 指定视图函数的请求方式,默认GET  defaults={& ...

  9. 【Flask】Flask Session操作

    ### session:1. session的基本概念:session和cookie的作用有点类似,都是为了存储用户相关的信息.不同的是,cookie是存储在本地浏览器,session是一个思路.一个 ...

随机推荐

  1. 让ie10/11支持非单页面的vue/es6

    为了满足某些客户的要求,最近让前端同学实现了ie 10(windows 7)/11(windows 10)支持多页面的vue/es6,基本参考如下: https://www.cnblogs.com/n ...

  2. GOROOT、GOPATH、GOBIN、project目录 _(转)

    前言:我觉得java程序员学golang很容易上手.关于GOROOT.GOPATH.GOBIN这些环境变量的设置,我隐约感觉到了java的影子(尽管我是一个C++程序员),唯一和java不同的是不能设 ...

  3. Android逆向破解:Android Killer使用

    目录   目录 软件介绍 Android Killer是一款可以对APK进行反编译的工具,它能够对反编译后的Smali文件进行修改,并将修改后的文件进行打包. 软件下载 这里用的是@昨夜星辰2012 ...

  4. [ Docker ] 基础的网络应用

    1. Docker 基本网络模型 Docker 有 4 种基本的网络模型: bridge 桥接模式 host 网络模式 container 联盟模式 none 模式 Docker daemon 在启动 ...

  5. 【Spring Cloud学习之三】负载均衡

    环境 eclipse 4.7 jdk 1.8 Spring Boot 1.5.2 Spring Cloud 1.2 主流的负载均衡技术有nginx.LVS.HAproxy.F5,Spring Clou ...

  6. windows系统常用命令

    dir 指定要列出的驱动器,显示当前文件夹下的文件   /?可显示所有命令 显示当前路径下的所有文件的绝对路径,包含子文件夹中的内容 D:\test > dir /b /s /o:n /a:a  ...

  7. netcore 步骤

    1.创建工程目录 d:\project 2.进入目录,创建解决方案 dotnet new sln 3.确定开发版本 dotnet --list-sdks //列出sdk版本 dotnet new gl ...

  8. RestTemplate的使用和原理你都烂熟于胸了吗?【享学Spring MVC】

    每篇一句 人圆月圆心圆,人和家和国和---中秋节快乐 前言 在阅读本篇之前,建议先阅读开山篇效果更佳.RestTemplate是Spring提供的用于访问Rest服务的客户端工具,它提供了多种便捷访问 ...

  9. redis底层实现的几种数据结构

    redis底层数据结构 一.简单动态字符串(SDS) 定义: struct sdshdr{ int len;    //SDS所保存的字符串长度 int free //记录buf数组中为使用的字节数量 ...

  10. 长乐国庆集训Day5

    T1 方阵 题目 [题目描述] 小澳最近迷上了考古,他发现秦始皇的兵马俑布局十分有特点,热爱钻研的小澳打算在电脑上还原这个伟大的布局. 他努力钻研,发现秦始皇布置兵马俑是有一定规律的.兵马俑阵总共有n ...