flask设置cookie,设置session,模拟用户认证、模拟管理后台admin、模拟用户logout
设置cookie
HTTP协议是无状态的,在一次请求响应结束后,服务器不会留下关于客户端状态的信息。但是对于某些web程序来说,客户端的信息有必要被记住,比如用户的登录状态,这样就可以根据用户的状态来返回不同的响应。为了解决这个问题就有cookie技术 。cookie技术通过在请求和响应报文中添加cookie数据来保存客户端的状态信息。
cookie值web服务器为了存储用户信息而保存在浏览器的文本数据。浏览器在一定时间内保存它,在下一次请求服务器时会附带这个cookie数据。cookie通常被用来进行用户的会话管理(登录状态),保存用户的个性化信息(比如语言设置,视频上次播放的位置,网站主题选项等)以及记录和手机用户浏览数据以来分析用户行为等。
在Flask中,如果想要在响应中加一个cookie,可以用Response类型的set_cookie()方法。要用这个方法,需要先使用make_response()方法手动生成一个响应对象,传入响应主体作为参数。这个响应对象默认实例化内置的Response类
Response类型的常用属性和方法:
set_cookie()方法支持多个参数来设置cookie的选项:
在response中设置cookie
set_cookie视图用来设置cookie,它会把URL中的name变量的值设置到名为name1的cookie里
set_cookie视图会在生成的的报文首部中创建一个Set_Cookie字段,
即”Set-Cookie: name1=xiaxiaoxu; Path=/”
from flask import Flask,make_response,redirect
@app.route('/hello/<name>')
def hello(name):
return '<h1>Hello, %s !</hi>' %name @app.route('/set/<name>')
def set_cookie(name):
#url_for()方法的第一个参数是视图函数名,第二个参数是该函数需要的参数
response = make_response(redirect(url_for('hello', name = 'xiaxiaoxu')))
#把url中name变量的值添加到cookie中name属性中
response.set_cookie('name1',name)
return response
if __name__ == '__main__':
app.run(debug = True)
结果:
在浏览器的cookie中,可以看到多了一个名为name1的cookie,它的值是”xiaxiaoxu”。
这个cookie会在关闭浏览器时过期。
第一个请求的响应中设置了cookie
当浏览器保存了服务器端设置的cookie后,当浏览器再次发送到该服务器的请求会自动携带设置的cookie信息,cookie的内容存储在请求首部的cookie字段中
第二个请求的请求中有携带cookie信息
Flask中,cookie可以通过请求对象的cookies属性读取。
我们修改一下hello视图函数,如果没有从查询参数中获取到name的值,就从cookies中寻找
@app.route('/')
@app.route('/hello')
def hello():
name = request.args.get('name')
if name is None:
name = request.cookies.get('name','Human')#从cookie中获取name值
return '<h1>Hello, %s</hi>' % name @app.route('/set/<name>')
def set_cookie(name):
response = make_response(redirect(url_for('hello',name = name)))
response.set_cookie('name1',name)
return response if __name__ == '__main__':
app.run(debug = True)
结果:
浏览器中 输入…/set/xiaxiaoxu
重定向后:地址是…/hello?name=xiaxiaoxu
这里的?后的参数是通过redirect(url_for('hello',name = name)这句生成的,因为hello()视图函数没有提供参数,所以这里直接把name=name这句加到了url后面
浏览器中输入127.0.0.1:5000/
此时name的值为空,那么name从cookies里面取值,取到一个默认值Human
session:即安全的cookie,就是把cookie数据进行了加密
session的作用
session在web程序中发挥很大的作用,其中最重要的功能是存储用户的认证信息。我们先来看看基于浏览器的用户认证是如何实现的。当我们使用浏览器登录某个社交网站时,会在登录表单中填写用户名和密码,单击登录按钮后,这会向服务器发送一个包含认证数据的请求。服务器接收请求后会查找对应账户,然后验证密码是否匹配,
如果匹配,就在返回的响应中设置一个cookie,比如,”login_user: sam”
响应被浏览器接收后,cookie会被保存在浏览器中。当用户再次想这个服务器发送请求时,根据请求附带的cookie字段中的内容,服务器上的程序就可以判断用户的认证状态,并识别出用户。
Flask 用session对象用来加密cookie数据
但是会带来用一个问题,在浏览器中手动添加和修改cookie是很容易的事,仅仅通过浏览器插件就可以实现。所以,如果直接把认证信息以明文的方式存储在cookie里,那么恶意用户就可以通过伪造cookie的内容来获得对网站的权限,冒用别人的账户。为了避免这个问题,我们需要对敏感的cookie内容进行加密。方便的是,Flask提供了session对象用来将cookie数据加密储存。
在编程中,session指用户会话(user session),又称为会话,即服务器和客户端/浏览器之间或桌面程序和用户之间建立的交互活动。在Flask中,session对象用来加密Cookie。默认情况下,它会把数据存储在一个名为session的cookie里。
设置程序密钥
session通过密钥对数据进行签名以加密数据,因此,我们得先设置一个密钥。这里的秘钥就是一个具有复杂度和随机性的字符串。
程序的秘钥可以通过Flask.secret_key属性或配置变量SECRET_KEY设置。
如:
app.secret_key = ‘secret string’
更安全的做法是把密钥写进系统环境变量(在命令行是用export或set命令),或者保存在.env文件中:
SECRET_KEY = secret string
然后在程序中用os模块提供的getenv()方法获取:
import os
…
app.secret_key = os.getenv(‘SECRET_KEY’, ‘secret string’)
在getenv()方法中的第二个参数是作为没有获取到环境变量时使用的默认值。
模拟用户认证:
使用session模拟用户的认证功能,下面代码是是登录的login视图
session对象可以像字典一样操作,我们向session中添加一个名为logged_in的cookie,值为True,表示用户已认证。
当我们使用session对象添加cookie时,数据会使用程序的密钥对其进行签名,加密后的数据存储在一块名为session的cookie里
from flask import redirect, session, url_for
import os
app.secret_key = os.getenv('SECRET_KEY','secret string') @app.route('/login')
def login():
session['logged_in'] = True #写入session
return redirect(url_for('hello')) @app.route('/')
@app.route('/hello')
def hello():
name = request.args.get('name')
if name is None:
name = request.cookies.get('name','Human')#从cookie中获取name值
return '<h1>Hello, %s</hi>' % name if __name__ == '__main__':
app.run(debug = True)
结果:
查看cookie页面,可以看到session的值是加密处理cookie后的值。使用session对象存储的cookie,用户可以看到其加密后的值,但不能修改。因为session中的内容使用密钥进行签名加密,一旦数据被修改,签名的值也会变化,这样在读取时,就会验证失败,对应的session值也会随之失效。
所以,除非用户知道密钥,否则无法对session cookie的值进行修改
第一次请求,在响应中设置了session
重定向后的请求数据:第二次请求时,会在请求头中加入session的信息
支持用户登录后,就可以根据用户的认证状态分别显示不同的内容,在login视图的最后,重定向到hello视图,我们修改一下hello视图,判断一下session中的认证状态,区分开处理
session中的数据可以像字典一样通过键读取,在这里只判断一下session中是否包含loggedd_in键,如果有则表示用户已经登录,在响应中加一行[Authenticated],否则显示[Not authenticated]
如果访问127.0.0.1:5000/login,就会登入当前用户,session中就会存储logged_in的信息,重定向到127.0.01:5000/hello后你会发现加载后的页面显示一行”[Authenticated]”,表示用户已经通过认证
from flask import redirect, session, url_for
import os
app.secret_key = os.getenv('SECRET_KEY','secret string') @app.route('/login')
def login():
session['logged_in'] = True #写入session
return redirect(url_for('hello')) @app.route('/')
@app.route('/hello')
def hello():
name = request.args.get('name')
if name is None:
name = request.cookies.get('name','xiaxiaoxu')#从cookie中获取name值
response = '<h1>Hello, %s</h1>' % name
#根据用户认证状态返回不同内容
if 'logged_in' in session:
response += '<p>[Authenticated]</p>'
else:
response += '[Not Authenticated]'
return response if __name__ == '__main__':
app.run(debug = True)
结果:
模拟管理后台admin的视图
from flask import session, abort
import os
app.secret_key = os.getenv('SECRET_KEY','secret string') @app.route('/login')
def login():
session['logged_in'] = True #写入session
return redirect(url_for('hello')) @app.route('/admin')
def admin():
if 'logged_in' not in session:
abort(403)
return 'welcom to admin page' if __name__ == '__main__':
app.run(debug = True)
结果:
没有存储登录cookie的情况下直接访问admin
会提示403
登录127.0.0.1:5000/login,写入session后,再次访问admin
此时session里已经存储了logged_in cookie信息,所以可以访问
模拟用户退出登录logout视图
已登录用户的退出,对应的操作就是它代表用户认证的logged_in cookie删除,这样用户的登录状态就失效了,通过session对象的pop方法实现:
@app.route('/logout')
def logout():
if 'logged_in' in session:
session.pop('logged_in')
return redirect(url_for('hello'))
结果:
在登录状态下,直接访问127.0.0.1:5000/logout
在logout视图中,清楚了session的logged_in信息,然后重定向到hello视图
重定向后的/hello页面的认证状态信息会变为[Not authenticatedd]
默认情况下,session cookie会在用户关闭浏览器时删除。通过将session.permanent属性设为True可以将session的有效期延长为Flask.permanent_session_lifetime属性值对应的datetime.timedelta对象,也可通过配置变量PERMANENT_SESSION_LIFETIME设置,默认为31天
尽管session对象会对cookie进行签名并加密,但这种方式仅能够确保session的内容不会被篡改,加密后的数据借助工具仍然可以轻易读取(即使不知道秘钥)。因此,绝对不能再session中存储敏感信息,比如用户密码。
flask设置cookie,设置session,模拟用户认证、模拟管理后台admin、模拟用户logout的更多相关文章
- flask中cookie和session设置
flask中cookie和session介绍 一.cookie: 在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户. ...
- flask中cookie和session介绍
flask中cookie和session介绍 一.cookie: 在网站中,http请求是无状态的.也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户.co ...
- linux学习(五)用户与组管理命令,以及用户信息文件解释
目录 (1)/etc/passwd文件 (2)/etc/shadow passwd命令 userdel命令 usermod命令 groupadd @(用户与组管理命令) linux是一个多用户多任务的 ...
- Flask中cookie和session设置与csrf原理攻防
Flask之操作cookie app.py from flask import Flask, request, Response app = Flask(__name__) @app.route('/ ...
- django设置cookie和session
1 设置cookie 本例中应用名称为cookie 模型model from django.db import models from django.db import models class Us ...
- Flask:cookie 和 session (0.1)
Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2 Cookie是什么?有什么用? 某些网站为了辨别用户身份.进行 session 跟踪而储存在用户本地终端上的数据(通常 ...
- Flask (二) cookie 与 session 模型
会话技术 Cookie 客户端端的会话技术 cookie本身由浏览器保存,通过Response将cookie写到浏览器上,下一次访问,浏览器会根据不同的规则携带cookie过来 特点: - 客 ...
- Cookie、Session和Token认证
目录 Cookie Session认证机制 Session的一些安全配置 Token认证机制 Token预防CSRF Session认证和Token认证的区别 前言:HTTP是一种无状态的协议,为了分 ...
- Mysql之用户认证授权管理
概述 Mysql的认证采用账号密码方式,其中账号由两个部分组成:Host和User:Host为允许登录的客户端Ip,User为当前登录的用户名. 授权没有采用典型的RBAC(基于角色的访问控制),而是 ...
随机推荐
- 第八节:分支开发之合并到master
流程:在客户端创建分支,修改代码,并push,然后在页面处理即可.(区别在于一个在客户端,一个在页面) 实际的开放中要记得打tag,不然到时候出问题了以后不知道从哪里开始.
- Jenkins打包安卓时提示没同意constraintLayout的license的解决方法
使用Jenkins打包安卓项目时,报错并失败,错误信息: You have not accepted the license agreements of the following SDK compo ...
- 火币网API文档——Websocket 请求与订阅示例
1. 访问地址 Pro 站行情请求地址为:wss://api.huobipro.com/ws HADAX 站行情请求地址为:wss://api.hadax.com/ws 2. 数据压缩 WebSock ...
- Linux安装go
在 http://golang.org/dl/下载最新的linux版本,并把它提取到/usr/local目录,在此目录下进行解压缩 $ sudo tar -xzf go1.9.1.linux-amd6 ...
- 关于获取路径path
String webPath = request.getServletPath(); log.info(webPath); 输出: /zjdlbb/zjdlbb/zjdlbb/test.ht log. ...
- centos mysql安装 完全版
在linux中安装数据库首选MySQL,Mysql数据库的第一个版本就是发行在Linux系统上,其他选择还可以有postgreSQL,oracle等 在Linux上安装mysql数据库,我们可以去其官 ...
- C 语言boolean 值判断
printf("%d\n", !0); 1 1 printf("%d\n", !0); #include <std ...
- 158A
#include <iostream> #include <algorithm> using namespace std; int main() { int groups[10 ...
- Linux命令:tar命令批量解压方法总结
tar命令批量解压方法总结 (2010-05-24 17:48:46) 转载▼ 标签: tar 批量解压 杂谈 分类: linux学习 由于linux的tar命令不支持批量解压,所以很多网友编写了好多 ...
- dfs1321
比较抽象吧,看到题时一点思想也没有,参考了别人的代码才知道...渣渣 #include <iostream>#include <stdio.h>#include <str ...