FLASK中的鉴权的插件Flask-HTTPAuth
在 Web 应用中,我们经常需要保护我们的 api,以避免非法访问。比如,只允许登录成功的用户发表评论等。Flask-HTTPAuth 扩展可以很好地对 HTTP 的请求进行认证,不依赖于 Cookie 和 Session。本文主要介绍两种认证的方式:基于密码和基于令牌 (token)。
1、安装
$ pip install Flask-HTTPAuth
2、基于密码的认证
为了简化代码,这里我们就不引入数据库了。
- 首先,创建扩展对象实例
from flask import Flask
from flask_httpauth import HTTPBasicAuth
app = Flask(__name__)
auth = HTTPBasicAuth()
这里有一点需要注意的是,我们创建了一个 auth 对象,但没有传入 app 对象,这跟其他扩展初始化实例有一点区别。
- 接着,写一个验证用户密码的回调函数
from werkzeug.security import generate_password_hash, check_password_hash
# 模拟数据库
books = ['The Name of the Rose', 'The Historian', 'Rebecca']
users = [{'username': 'ethan', 'password': generate_password_hash('6666')},{'username': 'peter', 'password': generate_password_hash('4567')}
]
# 回调函数
@auth.verify_password
def verify_password(username, password):user = filter(lambda user: user['username'] == username, users)if user and check_password_hash(user[0]['password'], password):g.user = usernamereturn Truereturn False
上面,为了对密码进行加密以及认证,我们使用 werkzeug.security 包提供的 generate_password_hash 和 check_password_hash 方法:generate_password_hash 会对给定的字符串,生成其加盐的哈希值;check_password_hash 验证传入的明文字符串与哈希值是否一致。
- 然后,我们在需要认证的视图函数上,加上 @auth.login_required 装饰器,比如
@app.route('/', methods=['POST'])
@auth.login_required
def add_book():_form = request.formtitle = _form["title"]if not title:return '<h1>invalid request</h1>'books.append(title)flash("add book successfully!")return redirect(url_for('index'))
上面完整的代码如下:
$ cat app.py
# -*- coding: utf-8 -*-
from flask import Flask, url_for, render_template, request, flash, \redirect, make_response, jsonify, g
from werkzeug.security import generate_password_hash, check_password_hash
from flask_httpauth import HTTPBasicAuth
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key'
auth = HTTPBasicAuth()
# 模拟数据库
books = ['The Name of the Rose', 'The Historian', 'Rebecca']
users = [{'username': 'ethan', 'password': generate_password_hash('6666')},{'username': 'peter', 'password': generate_password_hash('4567')}
]
# 回调函数
@auth.verify_password
def verify_password(username, password):user = filter(lambda user: user['username'] == username, users)if user and check_password_hash(user[0]['password'], password):g.user = usernamereturn Truereturn False
# 不需认证,可直接访问
@app.route('/', methods=['GET'])
def index():return render_template('book.html',books=books)
# 需要认证
@app.route('/', methods=['POST'])
@auth.login_required
def add_book():_form = request.formtitle = _form["title"]if not title:return '<h1>invalid request</h1>'books.append(title)flash("add book successfully!")return redirect(url_for('index'))
@auth.error_handler
def unauthorized():return make_response(jsonify({'error': 'Unauthorized access'}), 401)
if __name__ == '__main__':app.run(host='127.0.0.1', port=5206, debug=True)
$ cat templates/layout.html
<!doctype html>
<title>Hello Sample</title>
<div class="page">{% block body %} {% endblock %}
</div>
{% for message in get_flashed_messages() %}{{ message }}
{% endfor %}
$ cat templates/book.html
{% extends "layout.html" %}
{% block body %}
{% if books %}{% for book in books %}<ul><li> {{ book }} </li></ul>{% endfor %}
{% else %}<p> The book doesn't exists! </p>
{% endif %}
<form method="post" action="{{ url_for('add_book') }}"><input id="title" name="title" placeholder="add book" type="text"><button type="submit">Submit</button>
</form>
{% endblock %}
3、基于 token 的认证
很多时候,我们并不直接通过密码做认证,比如当我们把 api 开放给第三方的时候,我们不可能给它们提供密码,而是对它们进行授权,还可能会有时间限制,比如半年或一年等。这时候,我们往往通过一个令牌,也就是 token 来做认证,Flask-HTTPAuth 提供了 HTTPTokenAuth 对象来做这件事。
例如:
from flask import Flask, g
from flask_httpauth import HTTPTokenAuth
app = Flask(__name__)
auth = HTTPTokenAuth(scheme='Token')
tokens = {"secret-token-1": "john","secret-token-2": "susan"
}
# 回调函数,验证 token 是否合法
@auth.verify_token
def verify_token(token):if token in tokens:g.current_user = tokens[token]return Truereturn False
# 需要认证
@app.route('/')
@auth.login_required
def index():return "Hello, %s!" % g.current_user
if __name__ == '__main__':app.run()
上面,我们在初始化 HTTPTokenAuth 对象时,传入了 scheme=‘Token’。这个 scheme,是我们在发送请求时,在 HTTP 头 Authorization 中要用的 scheme 字段。用 curl 测试如下:
$ curl -X GET -H "Authorization: Token secret-token-1" http://localhost:5000/
结果:
Hello, john!
4、使用 itsdangerous 库来管理令牌
上面的令牌还是比较薄弱的,在实际使用中,我们需要使用加密的签名(Signature)作为令牌,它能够根据用户信息生成相关的签名,并且很难被篡改。itsdangerous 提供了上述功能,在使用之前请使用 pip 安装: $ pip install itsdangerous。
改进后的代码如下:
# -*- coding: utf-8 -*-
from flask import Flask, g
from flask_httpauth import HTTPTokenAuth
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key here'
auth = HTTPTokenAuth(scheme='Token')
# 实例化一个签名序列化对象 serializer,有效期 10 分钟
serializer = Serializer(app.config['SECRET_KEY'], expires_in=600)
users = ['john', 'susan']
# 生成 token
for user in users:token = serializer.dumps({'username': user})print('Token for {}: {}\n'.format(user, token))
# 回调函数,对 token 进行验证
@auth.verify_token
def verify_token(token):g.user = Nonetry:data = serializer.loads(token)except:return Falseif 'username' in data:g.user = data['username']return Truereturn False
# 对视图进行认证
@app.route('/')
@auth.login_required
def index():return "Hello, %s!" % g.user
if __name__ == '__main__':app.run()
将上面代码保存为 app.py,在终端运行,可看到类似如下的输出:
$ python app.py
Token for John: eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ3NjY5NzE0NCwiaWF0IjoxNDc2Njk1MzQ0fQ.eyJ1c2VybmFtZSI6IkpvaG4ifQ.vQu0z0Pos2Tgt5jBYMY5IYWUkTK9k3wE_RqvYHDqtyM
Token for Susan: eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ3NjY5NzE0NCwiaWF0IjoxNDc2Njk1MzQ0fQ.eyJ1c2VybmFtZSI6IlN1c2FuIn0.rk8JaTRwag0qiF9_KuRodhw6wx2ZWkOEhFln9hzOLP0* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
使用 curl 测试如下:
$ curl -X GET -H "Authorization: Token eyJhbGciOiJIUzI1NiIsImV4cCI6MTQ3NjY5NzE0NCwiaWF0IjoxNDc2Njk1MzQ0fQ.eyJ1c2VybmFtZSI6IkpvaG4ifQ.vQu0z0Pos2Tgt5jBYMY5IYWUkTK9k3wE_RqvYHDqtyM" http://localhost:5000/
# 结果
$ Hello, john!
相关文章:
FLASK中的鉴权的插件Flask-HTTPAuth
在 Web 应用中,我们经常需要保护我们的 api,以避免非法访问。比如,只允许登录成功的用户发表评论等。Flask-HTTPAuth 扩展可以很好地对 HTTP 的请求进行认证,不依赖于 Cookie 和 Session。本文主要介绍两种认证的方式:…...
linux万字图文学习进程信号
1. 信号概念 信号是进程之间事件异步通知的一种方式,属于软中断。 1.1 linux中我们常用Ctrlc来杀死一个前台进程 1. Ctrl-C 产生的信号只能发给前台进程。一个命令后面加个&可以放到后台运行,这样Shell不必等待进程结束就可以接受新的命令,启动新的进程。2. S…...
DataX实现Mysql与ElasticSearch(ES)数据同步
文章目录 一、Linux环境要求二、准备工作2.1 Linux安装jdk2.2 linux安装python2.3 下载DataX: 三、DataX压缩包导入,解压缩四、编写同步Job五、执行Job六、定时更新6.1 创建定时任务6.2 提交定时任务6.3 查看定时任务 七、增量更新思路 一、Linux环境要求…...
第二章 进程与线程 十、调度算法1(先来先服务、短作业优先、最高响应比优先)
目录 一、先来先服务算法 1、算法思想 2、算法规则 3、用于作业/进程调度 4、是否可抢占? 5、优缺点 优点: 缺点: 6、是否会导致饥饿 7、例子 二、短作业优先算法 1、算法思想 2、算法规则 3、用于作业/进程调度 4、是否可抢占? 5、优缺…...
windows平台 git bash使用
打开所在需要git管理的目录,鼠标右键open Git BASH here 这样就直接进来,不需要windows dos窗口下麻烦的切路径,windows和linux 路径方向不一致 (\ /) 然后git init 建立本地仓库,接下来就是git相关的操作了. 图形化界面查看 打开所在需要git管理的目录,鼠标右键…...
Linux系统之安装uptime-kuma服务器监控面板
Linux系统之安装uptime-kuma服务器监控面板 一、uptime-kuma介绍1.1 uptime-kuma简介1.2 uptime-kuma特点 二、本次实践环境介绍2.1 环境规划2.2 本次实践介绍2.3 环境要求 三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本3.3 检查系统是否安装Node.js 四、部署…...
计算机组成原理——基础入门总结(一)
本帖更新一些关于计算机组成原理的重点内容。由于博主考研时并不会考这门课,但是考虑到操作系统中又很多重要晦涩的概念涉及很多诸如内存、存储器、磁盘、cpu乃至各种寄存器的知识,此处挑选一些核心的内容总结复盘一遍——实现声明:本帖的内容…...
批量获取CSDN文章对文章质量分进行检测,有助于优化文章质量
📚目录 ⚙️简介✨分析获取步骤⛳获取文章列表☘️前期准备✨ 接口解析⚡️ 获取文章的接口 ☄️文章质量分接口⭐接口分析 ⌛代码实现:⚓核心代码:⛵测试用例:⛴ 运行效果:☘️增加Excel导出 ✍️结束 ⚙️简介 有时候我们写文章是为了记录当下遇到的bu…...
从一到无穷大 #17 Db2 Event Store,A Purpose-Built IoT Database Engine
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 引言Architectural overviewData format and meta-dataEnsuring fast ingestionMulti…...
9月16日,每日信息差
今天是2023年09月16日,以下是为您准备的15条信息差 第一、天猫超市首单“茅小凌”已由菜鸟送达,首单已由菜鸟供应链完成履约,18分钟送达消费者手中 第二、软银考虑对OpenAI进行投资。此外,软银还初步拟收购英国人工智能芯片制造…...
准备篇(二)Python 教程
Part 1 Python 基础语法区分输入与输出注释文本列表if 语句for 语句range() 函数走向编程的第一个例子Part 2 函数 和 数据结构函数数据结构del 语句列表详解元组集合字典循环的技巧Part 3 输入与输出读写文件打开文件 open()读文件写文件...
HTML+CSS画一个卡通中秋月饼
HTMLCSS画一个卡通中秋月饼🥮🥮🥮 中秋活动水个文章 整个divcss实现个月饼,给前端初学者一个练手的demo 效果图 思路 HTMl 先来个轮廓画脸上的东西:眼睛、眉毛、腮红、嘴巴眼睛丰富下瞳孔画20个花瓣 CSS 轮廓是要外…...
echarts的折线图,在点击图例后,提示出现变化,不报错。tooltip的formatter怎么写
在点击图例的年后,提示框会相应的变化,多选和单选都会响应变化。tooptip的重度在formatter tooltip:{show:true,trigger:"axis",alwaysShowContent:true,triggerOn:"mousemove",textStyle:{color:"#fff"},backgroundColor…...
C++中的auto是一个关键字,用于在编译时自动推导变量的类型
C中的auto是一个关键字,用于在编译时自动推导变量的类型。通过使用auto关键字,编译器可以根据变量的初始化表达式来确定其类型,从而省略了显式地指定类型的步骤。 使用auto关键字声明的变量必须在定义时进行初始化,以便编译器可以…...
VUE build:gulp打包:测试、正式环境
目录 项目结构 Gulp VUE使用Gulp Vue安装Gulp Vue定义Gulp.js package.json build文件夹 config文件夹 static-config文件夹 项目结构 Gulp Gulp是一个自动化构建工具,可以帮助前端开发者通过自动化任务来管理工作流程。Gulp使用Node.js的代码编写ÿ…...
1.使用turtle换一个五环2.设计这样一个程序:输入一个数字 判断它是不是一个质数
1.使用turtle换一个五环 import turtle turtle.pensize(15) turtle.penup() turtle.color(blue) turtle.goto(-150,-35) turtle.pendown() turtle.circle(60) turtle.penup() turtle.color(black) turtle.goto(0,-35) turtle.pendown() turtle.circle(60) turtle.penup() turtl…...
C语言希尔排序
希尔排序(Shell Sort)是插入排序的一种,也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本。希尔排序是非稳定排序算法。 希尔排序的基本思想是:先将整个待排序的记录序列分割成为若干子序列(由…...
KubeSphere 在互联网医疗行业的应用实践
作者:宇轩辞白,运维研发工程师,目前专注于云原生、Kubernetes、容器、Linux、运维自动化等领域。 前言 2020 年我国互联网医疗企业迎来了“爆发元年”,越来越多居民在家隔离期间不方便去医院看诊,只好采取在线诊疗的手…...
物联网:用python调入机器学习分析物联网数据入侵检测模块
要使用Python调用机器学习分析物联网数据入侵检测模块,您需要以下步骤: 安装Python和相关的机器学习库,如scikit-learn、pandas、numpy等。您可以使用pip命令来安装这些库。 准备输入数据。这些数据可以是来自物联网设备的原始数据ÿ…...
使用scss简化媒体查询
在进行媒体查询的编写的时候,我们可以利用scss与与编译器,通过include混入的方式对代码进行简化,从而大大提高了代码的可维护性,也减少了代码的编写量,废话不多说,直接上代码: // 断点列表 相当…...
win部署CRM
win部署crm) 1.phpstudy2.composer3.代码4.其他配置 周末锴哥让我帮他部署了一个CRM,写个教程,方便之后他用。锴哥用的是 NxCrm,先把代码下下来。 1.phpstudy 1.首先是下载小皮面板,配置php的环境。这里面下载了php8…...
Linux命令200例:dip用于用户与远程主机建立通信连接
🏆作者简介,黑夜开发者,CSDN领军人物,全栈领域优质创作者✌。CSDN专家博主,阿里云社区专家博主,2023年6月csdn上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师࿰…...
【每日一题】981. 基于时间的键值存储
981. 基于时间的键值存储 - 力扣(LeetCode) 设计一个基于时间的键值数据结构,该结构可以在不同时间戳存储对应同一个键的多个值,并针对特定时间戳检索键对应的值。 实现 TimeMap 类: TimeMap() 初始化数据结构对象void…...
IMU姿态解算,从IMU数据中计算旋转、速度、位置,IMU测量的原理
0. 预备 a. IMU测量值解释 IMU在测量时,得到的角速度或者加速度均是相对于地心惯性系结果,并且将该结果表示到Body坐标系下,就形成了最终的IMU输出。 记作: ω i b b \omega_{ib}^b ωibb,表示body系相对于惯性系的…...
【Qt-17】Qt调用matlab生成的dll库
matlab生成dll库 1、matlab示例代码 function BDCube(x,y)[x,y,z] cylinder(x,y);t1 hgtransform;s1 surf(3*x,3*y,4*z,Parent,t1);grid onview(3)shading interp end 2、matlab环境配置 首先检查自己的mcc编译器是否可用,输出以下命令: &#x…...
css经典面试题(二)
文章目录 1、清除浮动2、opacity: 0、visibility: hidden、display: none 的区别3、css画一个三角形4、常见的主流浏览器前缀5、重绘与重排的区别?6、如何优化图片7、CSS3 中 transition 和 animation 的属性分别有哪些8、居中为什么要使用 transform(为…...
jira搜索search issue条目rest实用脚本
官方文档链接地址: The Jira Cloud platform REST API 实用json请求脚本如下: {"fields": ["summary","status"],"jql": "project abc AND summary ~ 【%s】【coverity】 AND componentCoverity"…...
《C++ primer plus》精炼(OOP部分)——对象和类(5)
“学习是照亮心灵的火炬,它永不熄灭,永不止息。” 文章目录 类的自动和强制类型转换原始类型转换为自定义类型将自定义类型转换为原始类型 类的自动和强制类型转换 原始类型转换为自定义类型 可以用一个参数的构造函数来实现,例如ÿ…...
钉钉旧版服务端SDK支持异步方法的升级改造
最近项目中需要对接钉钉,有些钉钉 API 的访问需要使用旧版服务端 SDK 才能搞定,但是这个 SDK 使用的还是 .NET Framework 2.0 框架,不能跨平台部署,也不支持 async\await 的异步操作方法,Nuget 上也有其它用户改造的 .…...
【C语言】【数据存储】用%d打印char类型数据,猜结果是啥
题目代码如下: #include <stdio.h> int main() {char a -1;signed char b-1;unsigned char c-1;printf("a%d,b%d,c%d",a,b,c);return 0; }解题关键: 1.二进制存储:原码,反码,补码 互换 2.截断 3.整型…...
电子商务网站建设的核心是/长沙网址seo
一、基本搜索 逻辑符 与(空格)、或(OR)、非(-)。 ""全匹配搜索 加入双引号表示完全匹配搜索 *通配符 二、高级搜索 intitle:只搜索网页标题(即html的title指定的部分)含有关键词的页面 例&#x…...
php网站建设案例教程/河南网站优化公司哪家好
自动关联包含两种机制: 一种是loadrunner通过对比录制和回放时服务器响应的不同,而提示用户是否进行关联,用户可自己创建关联规则,这个功能可以方便的使我们获得需要关联的部分,但同时也存在一定的问题,如…...
番禺厂家关键词优化/seo外推软件
应用程序在运行过程中,会有大量需要处理的异常。在页面解析的一个工程中,会存在多个service类同时出现页面解析异常和解析结果入库异常,而这就表示在程序中需要一个机制,去统一处理这些异常,提供统一的异常处理。因为我…...
mip手机网站模板/新闻发稿平台有哪些?
前段时间,进行USB拷贝方面的测试,积累了几个测试脚本,也可以进行磁盘间的拷贝,放在这里备份。 主要实现功能: 从一个存储设备拷贝数据到另一个位置,并比较两次拷贝的数据是否一致,并判断系统是…...
胶州网站建设电话/优化大师
1.需求:设计代理 设计代理替代追求者向被追求者送玩偶、送花、送巧克力。 分析:追求者类和代理类都应该拥有送礼物的接口,只不过代理类送的礼物实际是追求者送的 2.实现 (1)被追求者类 被追求者Schoolgirl类只有na…...
wordpress顶部加载条/衡阳网站建设
1、对于N枚硬币每次翻转N-1枚,等价于有一枚硬币没有翻转,也等价于一枚硬币翻转了,那么对于第一个问题:最少次数也就是N次(直接输出) 2、对于N枚硬币翻N-1枚的理解:把整个过程分拆成两个步骤 1&a…...