【Flask】使用 werkzeug 安全地处理密码

使用 werkzeug 安全地处理密码

假设我们要实现一个登录注册的功能,最简单的方式是先创建一个表,有 usernamepassword 字段,然后再编写相应的登录和注册接口。

创建表

以下是一个简单的例子,展示了如何创建一个用户表并定义一些基本的操作:

import sqlite3def create_connection(db_file):""" 创建数据库连接 """conn = Nonetry:conn = sqlite3.connect(db_file)return connexcept Exception as e:print(e)return conndef create_table(conn):""" 创建一个表 """try:cursor = conn.cursor()cursor.execute("""CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY,username TEXT NOT NULL,password TEXT NOT NULL);""")conn.commit()except Exception as e:print(e)def add_user(conn, username, password):""" 向用户表中添加一个新用户 """try:cursor = conn.cursor()cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, password))conn.commit()except Exception as e:print(e)def main():database = "users.db"# 创建数据库连接conn = create_connection(database)# 创建表if conn is not None:create_table(conn)# 添加用户示例add_user(conn, 'username1', 'password1')else:print("无法创建数据库连接。")if __name__ == '__main__':main()

注意,这个示例中使用明文存储密码,这在实际应用中是不安全的。因此,应该使用像 werkzeug.security 中的 generate_password_hashcheck_password_hash 这样的方法来安全地处理密码。

  1. 安装 Werkzeug:
pip install Werkzeug
  1. 修改添加用户函数:使用 generate_password_hash 来存储密码的哈希值,而不是明文密码。
  2. 创建一个验证用户的函数:使用 check_password_hash 来验证提交的密码是否与存储的哈希匹配。
import sqlite3
from werkzeug.security import generate_password_hash, check_password_hashdef create_connection(db_file):""" 创建数据库连接 """# ... 代码不变 ...def create_table(conn):""" 创建一个表 """# ... 代码不变 ...def add_user(conn, username, password):""" 向用户表中添加一个新用户 """hashed_password = generate_password_hash(password)try:cursor = conn.cursor()cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, hashed_password))conn.commit()except Exception as e:print(e)def verify_user(conn, username, password):""" 验证用户凭据 """try:cursor = conn.cursor()cursor.execute("SELECT password FROM users WHERE username = ?", (username,))stored_password = cursor.fetchone()if stored_password and check_password_hash(stored_password[0], password):return Trueelse:return Falseexcept Exception as e:print(e)return False# main 函数和其他部分的代码不变

接口编写

首先,定义 User 模型

from database import dbclass User(db.Model):id = db.Column(db.Integer, primary_key=True)username = db.Column(db.String(80), unique=True, nullable=False)password = db.Column(db.String(120), nullable=False)def to_dict(self):return {'id': self.id,'username': self.username# 注意:不要返回密码}

然后,在 Flask 应用中添加注册和登录路由处理函数:

from flask import Flask, request, jsonify
from werkzeug.security import generate_password_hash, check_password_hash
# ... 其他导入 ...# ... Flask 应用的其他部分 ...@app.route('/api/register', methods=['POST'])
def register():data = request.get_json()# 确认数据有效性username = data.get('username')password = data.get('password')if not username or not password:return jsonify({'message': 'Missing username or password'}), 400# 检查用户名是否已存在if User.query.filter_by(username=username).first():return jsonify({'message': 'Username already exists'}), 400# 创建新用户hashed_password = generate_password_hash(password)new_user = User(username=username, password=hashed_password)db.session.add(new_user)db.session.commit()return jsonify({'message': 'User created successfully', 'user': new_user.to_dict()}), 201@app.route('/api/login', methods=['POST'])
def login():data = request.get_json()username = data.get('username')password = data.get('password')if not username or not password:return jsonify({'message': 'Missing username or password'}), 400# 检查用户是否存在user = User.query.filter_by(username=username).first()if user and check_password_hash(user.password, password):# 在这里,你应该生成并返回一个认证令牌return jsonify({'message': 'Login successful', 'user': user.to_dict()}), 200else:return jsonify({'message': 'Invalid credentials'}), 401# ... Flask 应用的其他部分 ...if __name__ == '__main__':app.run(debug=True)

注意

使用 Werkzeug 的 generate_password_hash 函数对密码进行哈希处理后,原始密码将不再可见,因此不再存储明文密码。这是哈希算法的一种基本原则,密码不应该以明文形式存储,以提高安全性。

因此,一旦密码被哈希处理,就不再能够直接查看密码的明文值。验证密码时,您将使用 check_password_hash 函数来比较哈希值,而不是查看明文密码。

当然,我们可以使用 Werkzeug 验证密码:、

from werkzeug.security import generate_password_hash, check_password_hash# 生成哈希密码
password = "userpassword123"
hashed_password = generate_password_hash(password)# 检查密码
user_input_password = "userpassword123"  # 用户输入的密码
if check_password_hash(hashed_password, user_input_password):print("密码正确")
else:print("密码错误")

在上述示例中,generate_password_hash 用于创建哈希密码,而 check_password_hash 用于验证用户提供的密码是否与哈希密码匹配。由于哈希是单向的,所以无法从哈希密码还原出明文密码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/618983.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day07

1.return关键字的用法return 在有返回值的方法中使用return 返回值;return 关键字书写以后后面的代码就不能写了2.声明方法的四种形式无参无返回值的语法格式有参无返回值的无参有返回值的有参有返回值的3.什么是形参,什么是实参在方法的声明处,写的变量…

年日历实现, 2、维护工作日和休息日, 3、初始化法定节假日

you:请帮我用vue2实现如下功能:1、年日历实现, 2、维护工作日和休息日, 3、初始化法定节假日 当你想要使用Vue.js 2实现年度日历,并维护工作日和休息日以及初始化法定节假日时,你可以考虑以下步骤。 首先&#xff0c…

全志图形引擎 以 F1C200s 为例介绍

全志图形引擎的思路在很多自家芯片上是大差不差的。这些芯片包括但不限于:F1C100s、F1C200s、V3S、A64、T113、H8、H3、A83。 F1C200s 和 F1C100s 相差极小,仅集成内存大小有所差别。 下面以 F1C200s 为例讲解全志图形引擎。 F1C200s的显示系统由以下四部分组成: 时序控制…

使用pandas按照商品和下单人统计下单数据

目录 一:需求描述 二:代码实现 三:注意事项 一:需求描述 最近运营那边给到一个excel表格,是一个小程序用户的下单数据,要以商品为维度,统计用户下单情况,主要是下单的商品总金额&…

多进程 案例

from multiprocessing import Process, Queueclass MyProcess(Process):def __init__(self, q, i):super().__init__()self.q qself.i idef run(self):print(子进程%s 开始put数据 % self.i)self.q.put(我是%s 通过Queue通信 % self.i)self.q.put(我是%s 通过Queue通信 % 2)i…

SpringBoot-Dubbo-Zookeeper

Apache Dubbo&#xff1a;https://cn.dubbo.apache.org/zh-cn/overview/home/ 依赖 <!--dubbo--> <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>2.7.3</versio…

CMake+大漠插件的应用开发——处理dm.dll,免注册调用大漠插件

文章目录 CMake大漠插件的应用开发——处理dm.dll&#xff0c;免注册调用大漠插件简介环境项目结构配置编译环境编码-直接调用 dll编码-生成tlh文件&#xff0c;便于提示 CMake大漠插件的应用开发——处理dm.dll&#xff0c;免注册调用大漠插件 简介 网上有一种使用方式是&am…

Navicat连接不上虚拟机中linux的dockers创建的mysql

说明&#xff1a;这个问题可能只是我的个人问题&#xff0c;记录一下吧。当发现这个问题的时候&#xff0c;去网上搜素了一下&#xff0c;搜到的文章基本上都是通过在mysql中设置允许远程访问解决的&#xff0c;然后我也跟着尝试了一下&#xff0c;问题并没有解决。后面就乱七八…

golang学习-golang结构体和Json相互转换

1、结构体转为json对象 v, _ : json.Marshal(student) jsonStr : string(v) // 结构体转为json对象 2、json字符串转为结构体 var s1 Student err : json.Unmarshal([]byte(str), &s1) //json 字符串转为结构体 3、结构体标签 表示的是转换为json对象时&#xff0c;ID字段…

allegro PCB设计心得笔记(二) PCB板框设计心得

Cadence Allegro软件设计PCB板框时&#xff0c;使用Add -> line&#xff0c;在Option选择Board Geometry/Outline&#xff0c;根据PCB需要输入对应坐标&#xff0c;设计好板框。 使用Z-Copy命令设计Route Keepin和Package Keepin时&#xff0c;需要先使用使用Shape -> Co…

【Python】Python语言 3小时速通(有C语言基础版)

python从入门到实践 变量 message"hello world"并不需要指出变量类型 方法 tittle()#以首字母大写的形式输出单词upper()#全部大写输出lower()#全部小写输出存储数据时经常使用lower&#xff0c;因为无法确保数据是大写还是小写 rstrip()#输出删除字符串尾部多余…

YOLOv5涨点改进:多层次特征融合(SDI),小目标涨点明显,| UNet v2,比UNet显存占用更少、参数更少

💡💡💡本文全网独家改进:多层次特征融合(SDI),能够显著提升不同尺度和小目标的识别率 💡💡💡在YOLOv5中如何使用 1)iAFF加入Neck替代Concat; 💡💡💡Yolov5/Yolov7魔术师,独家首发创新(原创),适用于Yolov5、Yolov7、Yolov8等各个Yolo系列,专栏文…

RabbitMQ 的基本概念

一 MQ 的基本概念 1 MQ概述 MQ全称 Message Queue&#xff08;消息队列&#xff09;&#xff0c;是在消息的传输过程中保存消息的容器。多用于分布式系统之间进行通信。消息队列就是所谓的存放消息的队列。 消息队列解决的不是存放消息的队列的⽬的&#xff0c;解决的是通信问…

三、GCC编译:链接

代码准备 main.c extern int shared; extern void func(int *a, int *b); int main(){int a 100;func(&a, &shared);return 0; }func.c int shared 1; int tmp 0; void func(int *a, int *b){tmp *a;*a *b;*b tmp; }静态链接 编译 gcc -static -fno-stack-p…

VB6 VBA asp的RecordSet.GetRows方法

1.VBA调用ADO执行SQL语句获取查询结果&#xff0c;通过RecordSet.GetRows方法获取到的数组是行列转置后的数组。 2.如果通过application.transpose对RecordSet.GetRows方法获取到的数组再进行转置&#xff0c;如果报错“运行时错误438&#xff1a;对象不支持该属性或方法”&am…

TypeScript学习笔记、鸿蒙开发学习笔记

变量定义方式 # 变量声明 let msg: string douzi console.log(msg) let num: number 20 console.log(num) let end: boolean true console.log("end" end) let a: any 10 a douzi console.log(a) let p {name:"douzi",age:20} console.log(p.name)…

hls转流服务的nginx配置和一些脚本

前言 当今&#xff0c;流媒体服务已成为互联网中不可或缺的重要组成部分。HLS&#xff08;HTTP Live Streaming&#xff09;作为一种流媒体传输协议&#xff0c;被广泛应用于视频直播、点播等应用场景中。而Nginx作为一款高性能的Web服务器&#xff0c;也可以被用于构建HLS转流…

《每天十分钟》-红宝书第4版-集合引用类型(二)

接着奏乐接着抄&#xff0c;续着上篇的数组 迭代器方法 const a ["zhangsan", "lisi", "wangwu"]; // 因为这些方法都返回迭代器&#xff0c;所以可以将它们的内容 // 通过 Array.from()直接转换为数组实例 const aKeys Array.from(a.keys(…

cmake-将源文件编译为可执行文件

文章目录 准备工作创建cmake文件编译源代码需要的文件不在同一个文件夹的情况 准备工作 首先我们准备三个文件 add.h int add(int a,int b);add.cpp int add(int a,int b) {return ab; }main.cpp #include "add.h" #include <iostream> int main() {in…

Multi-Concept Customization of Text-to-Image Diffusion——【代码复现】

本文是发表于CVPR 2023上的一篇论文&#xff1a;[2212.04488] Multi-Concept Customization of Text-to-Image Diffusion (arxiv.org) 一、引言 本文主要做的工作是对stable-diffusion的预训练模型进行微调&#xff0c;需要的显存相对较多&#xff0c;论文中测试时是在两块GP…