Flask简单调用Redis、MySQL和生成token及token验证

news/2024/5/1 5:50:11/文章来源:https://blog.csdn.net/make_progress/article/details/126921081

项目地址:https://github.com/MasonYyp/myflask

1 安装python基础环境

# 安装flask
pip install flask# 安装redis
pip install redis# 安装操作MySQL的包
pip install flask-sqlalchemy
pip install pymysql
# 安装序列化包
pip install flask-marshmallow
pip install marshmallow-sqlalchemy# 安装生成token相关的包
pip install pyjwt# 安装生成验证码的包
pip install captcha

2 Docker安装redis和mysql

2.1 redis.conf

# redis.conf
# 可远程连接
# bind 127.0.0.1
# 解除保护模式
protected-mode no
# 数据持久化
appendonly yes
# 设置密码
requirepass 123456

2.2 创建redis容器

sudo docker run -itd \
--restart=always \
--name fl_redis \
-p 6379:6379 \
-v /home/fl_redis/redis.conf:/etc/redis/redis.conf \
-v /home/fl_redis/data:/data \
redis:6.2.2 redis-server /etc/redis/redis.conf

2.3 创建MySQL容器

# 安装MySQL,密码是123456
sudo docker run -itd \
--restart=always \
--name fl_mysql \
-p 3306:3306 \
-v /home/mysql/conf:/etc/mysql/conf.d \
-v /home/mysql/data:/var/lib/mysql \
-v /home/mysql/log:/var/log/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7

进入MySQL容器创建数据库

create database myflask default character set utf8mb4 collate utf8mb4_unicode_ci;

3 vue前端

3.1 前端页面

<template><div class="login"><div>Login</div><div class="lo_cont"><div>用户名:<el-input v-model="name" placeholder="请输入用户名"></el-input></div><div>密码:<el-input v-model="pwd" placeholder="请输入密码" show-password></el-input></div><div>验证码:<img v-bind:src="codeImgSrc"><el-input v-model="code" placeholder="请输入验证码"></el-input></div><el-button v-on:click="login">提交</el-button></div></div>
</template><script>import axios from 'axios'// 按需引入ElementUI组件
import 'element-ui/lib/theme-chalk/index.css' 
import { Input, Button } from 'element-ui'export default {name: 'Login',props: {msg: String},components:{elInput: Input,elButton: Button},data:function(){return{name:"mason",pwd:"123456",code:"",codeKey: "",codeImgSrc: ""}},created:function(){this.get_captcha()},methods:{get_captcha: function(){axios.post("/flask/public/captcha").then(res=>{console.log(res.data)let data = res.data;this.codeImgSrc = data.code_img;this.codeKey = data.code_key;})},login: function(){let param = {name: this.name,pwd: this.pwd,code_key: this.codeKey,code: this.code}// 使用json方式传参axios.post("/flask/public/login", param).then(res=>{let token = res.dataconsole.log(token);})}}
}
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>.lo_cont>>>.el-input{width: 30%;
}</style>

3.2 截图

前端截图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UCayOZby-1663496733483)(Flask使用Redis存储tocken.assets/image-20220918172017664.png)]

4 flask工程

4.1 工程目录

在这里插入图片描述

4.2 代码

4.2.1 main

from flask import Flaskfrom route.interceptor import before_interceptor
from route.operate_blueprint import OperateBlueprint
from dao.base_db.mysql_db import init_mysql_dbapp = Flask(__name__)# 设置拦截器
@app.before_request
def route_interceptor():return before_interceptor()# 初始化蓝本
operate_blueprint = OperateBlueprint(app)
operate_blueprint.init_blueprint()# 初始化MySQL
init_mysql_db(app)# Run the app
if __name__ == '__main__':app.run(host='0.0.0.0', port=5000)

4.2.2 config目录

4.2.2.1 common.py
import osdef get_root_path():cur_path = os.path.abspath(os.path.dirname(__file__))root_path, _ = os.path.split(cur_path)return root_path
4.2.2.2 db_conf.py

class RedisConf:# 配置基本参数pwd = "123456"host = "192.168.108.100"port = 6379class MysqlConf:acc = "root"pwd = "123456"host = "192.168.108.100"port = 3306db = "myflask"redis_conf = RedisConf()
mysql_conf = MysqlConf()

4.2.3 dao目录

4.2.3.1 base_db.mysql_db.py
from flask import Flask
from config.db_conf import mysql_conf
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow# 添加pymysql驱动,连接MySQL数据库
import pymysql
pymysql.install_as_MySQLdb()# 创建MySQL单实例
mysql_db = SQLAlchemy()# 创建Schema
mysql_schema = Marshmallow()# 初始化MySQL数据库
def init_mysql_db(app: Flask):# 配置MySQL数据库urldb_url = "mysql://" + mysql_conf.acc + ":" + mysql_conf.pwd + "@" + mysql_conf.host + ":" + str(mysql_conf.port) + "/" + mysql_conf.dbapp.config["SQLALCHEMY_DATABASE_URI"] = db_url# 关闭sqlalchemy自动跟踪数据库app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False# 显示底层执行的SQL语句app.config['SQLALCHEMY_ECHO'] = True# 解决‘No application found. Either work inside a view function or push an application context.’app.app_context().push()# 初始化appmysql_db.init_app(app)# 初始化schemamysql_schema.init_app(app)# 初始化table
def init_table():# 删除表mysql_db.drop_all()# 创建表mysql_db.create_all()
4.2.3.2 base_db.redis_db.py
import redis
from config.db_conf import redis_confclass RedisDB:# 初始化redisdef __init__(self):# 设置主机、端口号和密码redis_pool = redis.ConnectionPool(host=redis_conf.host, port=redis_conf.port, password=redis_conf.pwd, decode_responses=True)self.__strict_redis = redis.StrictRedis(connection_pool=redis_pool)# 在redis中添加键值,并设置过期时间def set(self, key, value, expiry):self.__strict_redis.set(name=key, value=value, ex=expiry)# 获取值def get(self, key):return self.__strict_redis.get(name=key)# 获取键值的剩余时间def ttl(self, key):# Time To Livereturn self.__strict_redis.ttl(name=key)# 设置单例模式
redis_db = RedisDB()
4.2.3.3 base_db.mysql_db.model.user_model.py
from dao.base_db.mysql_db import mysql_db as db# 创建用户表
class User(db.Model):# 用户__tablename__ = "tf_user"id = db.Column(db.Integer, nullable=False, primary_key=True, autoincrement=True)name = db.Column(db.String(32), nullable=False, unique=True)pwd = db.Column(db.String(32), nullable=False)def __repr__(self):# 显示对象中的信息return "User object: name=%s" % self.name
4.2.3.4 base_db.mysql_db.schema.user_schema.py
from dao.base_db.mysql_db import mysql_schema as ma
from dao.mysql_dao.model.user_model import User"""
# 序列化方法1
# 需要
注意flask-marshmallow的版本:flask-marshmallow<0.12.0class AuthorSchema(ma.ModelSchema)flask-marshmallow>=0.12.0 (recommended)class AuthorSchema(ma.SQLAlchemyAutoSchema)
"""# 使用flask_marshmallow初始化model
class UserSchema(ma.SQLAlchemyAutoSchema):class Meta:model = Userload_instance = True"""# 序列号方法2
from marshmallow import Schema, fields# 使用marshmallow初始化model
class UserSchema(Schema):id = fields.Integer()name = fields.String()pwd = fields.String()class Meta:# 设置序列化字段fields = ["id", "name", "pwd"]# 转化为有序字典ordered = True"""

4.2.3 route目录

4.2.3.1 interceptor.py
from flask import request
from dao.base_db.redis_db import redis_db# 设置拦截器
def before_interceptor():# Pass white listif white_list():passelse:res_status = check_token()if res_status == 1:passelse:return res_status# 设置白名单
def white_list():url_white_list = ["/flask/public/captcha", "/flask/public/login", "/flask/public/register", "/flask/public/initdb"]cur_url = request.path# Pass the urlif cur_url in url_white_list:return Trueelse:return False# 设置token
def check_token():token = request.headers.get("token")if token is None:return "Token None"token_ttl = redis_db.ttl(token)# 验证码已经过期if token_ttl <= 0:return "Token expired"# 获取redis中的coderedis_token = redis_db.get(token)if token != redis_token:return "Token error"return 1
4.2.3.2 operate_blueprint.py
# Configure Blueprintfrom route.public_route import public_bp
from route.userinfo import userinfo_bpclass OperateBlueprint():# Init the appdef __init__(self, app):self.__app = appself.__base_path = "/flask"# 初始化蓝本def init_blueprint(self):# Register the blueprintself.__app_register_blueprint(public_bp)self.__app_register_blueprint(userinfo_bp)# 在Flask中添加蓝本def __app_register_blueprint(self, blueprint):self.__app.register_blueprint(blueprint, url_prefix=self.__base_path + blueprint.name)
4.2.3.3 public_route.py
from flask import Blueprint, jsonify, request
from service.public_service import register_user, login_user, generate_captcha, create_tablepublic_bp = Blueprint("/public", __name__)@public_bp.route("/captcha", methods=['POST'])
def captcha():captcha_dict = generate_captcha()return jsonify(captcha_dict)@public_bp.route("/login", methods=['POST'])
def login():# 获取json数据data = request.get_json()print(data)res = login_user(data['name'], data['pwd'], data['code_key'], data['code'])return jsonify(res)@public_bp.route("/register", methods=['POST'])
def register():register_user()return "register"@public_bp.route("/initdb", methods=['POST'])
def init_mysql_db():return create_table()
4.2.3.4 userinfo.py
from flask import Blueprint
userinfo_bp = Blueprint("/userinfo", __name__)@userinfo_bp.route("/info", methods=['POST'])
def login():return "Mason"

4.2.4 service目录

public_service.py

from dao.base_db.redis_db import redis_db
from dao.base_db.mysql_db import mysql_db, init_tablefrom dao.mysql_dao.model.user_model import User
from dao.mysql_dao.schema.user_schema import UserSchemafrom util.operate_captcha import operate_captcha
from util.operate_token import operate_tokendef generate_captcha():# 生成验证码code = operate_captcha.generate_code()# 生成图片验证码image_base64_str = operate_captcha.generate_captcha_base64(code)# 生成唯一keycode_key = operate_captcha.generate_code_key()# 存入Redisredis_db.set(code_key, code.casefold(), 30)data = {"code_key": code_key,"code_img": image_base64_str}return datadef register_user():user = User()user.name = "mason"user.pwd = "123456"# 添加数据mysql_db.session.add(user)mysql_db.session.commit()def login_user(name, pwd, code_key, code):code_ttl = redis_db.ttl(code_key)# 验证码已经过期if code_ttl <= 0:return -1# 获取redis中的coderedis_code = redis_db.get(code_key)# 验证码过期if redis_code != code.casefold():return -2# 查询数据user = User.query.filter_by(name=name, pwd=pwd).first()# 序列号对象user_json = UserSchema().dump(user)print(user_json)# 生成tokentoken = operate_token.create_token(user.id, user.name, 60)# 添加到redisredis_db.set(token, token, 60)return tokendef create_table():init_table()return "create table"

4.2.5 util目录

4.2.5.1 operate_captcha.py
from captcha.image import ImageCaptcha
import randomimport base64
import uuidclass OperateCaptcha:def generate_code(self, code_len=4):code_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'chars_len = len(code_chars) - 1code = ''for _ in range(code_len):index = random.randint(0, chars_len)code = code + code_chars[index]return codedef generate_captcha_base64(self, code):# 生成验证码image = ImageCaptcha()# 生成图片BytesIOimg_bytes_io = image.generate(code)# 转化为字符串image_base64 = base64.b64encode(img_bytes_io.read())image_base64_str = "data:image/png;base64," + str(image_base64, 'utf-8')return image_base64_strdef generate_code_key(self):# 生成唯一标识code_key = str(uuid.uuid1())return code_keyoperate_captcha = OperateCaptcha()
4.2.5.2 operate_token.py
import jwt
from datetime import datetime, timedelta# 操作Token
class OperateToken:def __init__(self):self._private_key = "123456"pass# 创建tokendef create_token(self, user_id, user_name, expiry_seconds):# Calculate expiry timeexpiry_time = datetime.utcnow() + timedelta(seconds=expiry_seconds)payload = {'exp': expiry_time,'user_id': user_id,'username': user_name}# 加密encode_jwt = jwt.encode(payload, self._private_key, algorithm='HS256')return encode_jwt# 验证tokendef check_token(self, token):decode_jwt = "-1"# 解密try:decode_jwt = jwt.decode(token, self._private_key, algorithms=['HS256'])except jwt.PyJWTError:print("Token is error!")return decode_jwtoperate_token = OperateToken()

5 postman截图

5.1 初始化数据表

http://127.0.0.1:5000/flask/public/initdb

5.2 注册接口

http://127.0.0.1:5000/flask/public/register

在这里插入图片描述

5.3 调用info接口

调用权限口需要验证token

http://127.0.0.1:5000/flask/userinfo/info

在这里插入图片描述

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

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

相关文章

详细解读-Spring请求处理

SpringMvc_请求处理 Spring MVC 框架也是一个基于请求驱动的 Web 框架&#xff0c;并且使用了前端控制器模式&#xff08;是用来提供一个集中的请求处理机制&#xff0c;所有的请求都将由一个单一的处理程序处理来进行设计&#xff0c;再根据请求映射规则分发给相应的页面控制…

7.Docker 常规软件安装

Docker 常规软件安装&#xff08;Tomcat、MySQL、Redis&#xff09; 1. 总体步骤 搜索镜像拉取镜像查看镜像启动镜像容器实例 服务端口映射 停止容器移除容器 2. Tomcat 安装 搜索&#xff1a;docker search tomcat 拉取&#xff1a;docker pull tomcat 查看&#xff1a…

【C++】STL常用容器:string类(详解及模拟实现)

前言&#xff1a; 关于STL的学习&#xff0c;就从最常用的string类开始吧&#xff01;在本篇博客中会详细介绍string的使用方法和细节&#xff0c;最后再模拟实现一个string类。 承接上文&#xff1a;【C】模板初阶 | STL简介 废话不多说&#xff0c;下面直接进入正题 文章目录…

【BAT-表姐御用04ren进阶命令】文件数字顺序命名及改名(含命令解释)

1、bat实现数字顺序命名 echo off setlocal enabledelayedexpansion set count100 for /f "delims" %%i in (dir /b *.jpg,*.png,*.bmp,*.jpeg,*.gif,*.m4v) do call:Rename "%%~i" pause exit:Rename set /a count1 if /i "%~1""伯爵与妖…

Postgresql源码(78)plpgsql中调用call proc()时的参数传递和赋值(pl参数)

《Postgresql源码&#xff08;77&#xff09;plpgsql中参数传递和赋值&#xff08;pl参数&#xff09;》 《Postgresql源码&#xff08;78&#xff09;plpgsql中调用call proc()时的参数传递和赋值&#xff08;pl参数&#xff09;》 总结 调用者在exec_stmt_call中拼接ParamLi…

第12章:动态内存【C++ Primer 中文版 第五版】阅读笔记 + 源码解析

动态内存12.1 动态内存与智能指针shared_ptr类对象的生存周期对象类型生存周期全局对象创建&#xff1a;程序启动时。 销毁&#xff1a;程序结束时。局部自动对象创建&#xff1a;进入其定义所在的程序块时。 销毁&#xff1a;离开其定义所在的程序块时。局部static对象创建&am…

软件设计师笔记-----系统安全分析与设计

五、系统安全分析与设计 5.1、信息系统安全属性 安全属性包括 保密性&#xff1a;最小授权原则、防暴露、信息加密、物理保密完整性&#xff1a;安全协议、校验码、密码验、数字签名、公证可用性&#xff1a;综合保障&#xff08;IP过滤、业务流控制、路由选择控制、审计眼踪…

复习单片机:定时器/计数器部分(内含:1.51 单片机定时器原理 +2.51 单片机定时/计数器结构+3.定时器配置+4.代码部分+5.实验现象)

1.51 单片机定时器原理STC89C5X 单片机内有两个可编程的定时/计数器 T0、T1 和一个特殊功能定 时器 T2。定时/计数器的实质是加 1 计数器&#xff08;16 位&#xff09;&#xff0c;由高 8 位和低 8 位两 2个寄存器 THx 和 TLx 组成。 它随着计数器的输入脉冲进行自加 1&#x…

初识kotlin(初用kotlin一时爽、一直用一直爽)

kotlin历程 2011年7月&#xff0c;JetBrains推出Kotlin项目&#xff0c;这是一个面向JVM的新语言2012年2月&#xff0c;JetBrains以Apache 2许可证开源此项目2016年2月15日&#xff0c;Kotlin v1.0发布。这被认为是第一个官方稳定版本&#xff0c;并且JetBrains已准备从该版本…

【云原生】zookeeper + kafka on k8s 环境部署

文章目录一、概述二、Zookeeper on k8s 部署1&#xff09;添加源2&#xff09;修改配置3&#xff09;开始安装4&#xff09;测试验证5&#xff09;Prometheus监控6&#xff09;卸载三、Kafka on k8s 部署1&#xff09;添加源2&#xff09;修改配置3&#xff09;开始安装4&#…

pytorch线性代数的基本操作

线性代数的基本操作 标量由只有一个元素的张量表示 import torch xtorch.tensor([3.0]) ytorch.tensor([2.0]) xy,x*y,x/y,x**y向量视为标量值的组成 通过张量的索引来访问任一元素 xtorch.arange(4) x,x[3] #张量的长度 len(x) #张量的形状 x.shape对称矩阵 AAT Btorch.ten…

一文看懂线性回归(保姆级别 含源码)

来源: AINLPer 微信公众号&#xff08;每日论文干货分享&#xff01;&#xff01;&#xff09; 编辑: ShuYini 校稿: ShuYini 时间: 2022- 9 -18 引言 最近作者网上看了很多关于线性回归的帖子&#xff0c;个人感觉比较乱&#xff0c;所以打算自己整理一版&#xff0c;希望能把…

(41)STM32——外部SRAM实验笔记

目录 学习目标 成果展示 硬件知识 特点 功能框图 读时序 ​编辑写时序 FSMC驱动 寄存器 闪存片选控制寄存器 硬件 配置 代码 总结 学习目标 今天我们要学习的是有关外部SRAM实验&#xff0c;其实F&#xff14;内部也是有一个&#xff11;&#xff19;&#x…

本周大新闻|索尼PS VR2体验首次公开;Meta Quest Pro开箱视频曝光

本周大新闻&#xff0c;AR方面&#xff0c;沃尔玛App加入AR试穿功能&#xff1b;谷歌搜索AR新增60个行星、卫星模型&#xff1b;Niantic宣布与漫威娱乐合作打造新款LBS AR游戏&#xff1b;AR眼镜ActiveLook打通Apple Watch。 VR方面&#xff0c;索尼PS VR2体验首次公开&#x…

2022年笔试知识总结展望

应届生的笔试知识总结&#xff0c;温故而知新&#xff0c;看看知识加深印象&#xff0c;希望学得更好&#xff0c;有个好结果。 目录 1. TCP的拥塞控制 2. position属性 3. [‘1‘, ‘2‘, ‘3‘].map(parseInt) 输出结果 4. 排序算法的稳定性分析 1&#xff09;稳定的排…

事件研究法与其应用(2)---Excel实操步骤

我们借着学习事件研究法的应用,可以用Excel和Stata等软件进行操作。 今天这主要是利用EXCEL计算累积异常收益率。 在正式开展实操之前,我们先回顾一下事件研究法的步骤(尤其是我们写作论文的时候): 事件研究法计算步骤: 1. 获取数据,定义事件期 2.计算估计期间个股与市…

npm yarn 报错

目录npm yarn报错yarn: 无法加载文件 npm yarn报错 yarn: 无法加载文件 win10系统,yarn : 无法加载文件 C:\Users\丽丽小可爱\AppData\Roaming\npm\yarn.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 ... 导致此错误的原因是,PowerShell 执行策略,默认设置为Rest…

JSON 数据类型转换工具

简介 本文介绍一款数据类型转换工具&#xff0c;可以将JSON格式数据转换成YAML、MYSQL、XML、TOML、JavaScript等数据类型。 背景 在日常的开发工程中&#xff0c;我们经常使用JSON表达数据&#xff0c;但有些时候我们需要使用YAML、JavaScript等语言表达数据。因此&#xf…

HTML + HTTP请求 +CSS知识点

文章目录HTML1.HTML元素2.HTML页面3.常见元素1&#xff09;文本2&#xff09;多媒体3&#xff09;表单作用与语法常见表单项案例体验4.HTTP请求1&#xff09;请求组成2&#xff09; 请求方式与数据格式get 请求示例post 请求&#xff08;默认格式&#xff09;示例json 请求&…

Python必知必会 os 模块详解

文章目录Python os 模块os模块的常用操作os.path模块os.open()模块Python os 模块 os是“operating system”的缩写&#xff0c;os模块提供各种 Python 程序与操作系统进行交互的接口&#xff0c;使用os模块&#xff0c;一方面可以方便地与操作系统进行交互&#xff0c;另一方…