当前位置: 首页 > news >正文

【自学开发之旅】Flask-会话保持-API授权-注册登录

http - 无状态-无法记录是否已经登陆过
#会话保持 – session cookie
session – 保存一些在服务端
cookie – 保存一些数据在客户端

session在单独服务器D上保存,前面数个服务器A,B,C上去取就好了,业务解耦。—》》现在都是基于token的验证。
以上是基于BS架构

API授权
由服务端完全把控
三张表,api_token,app_permission,api_permission
多对多的关系:一个账号(服务端给的)可以有多个url权限,同一个url可以被多个账号授权。

models/user.py

from . import db#API授权表的模型
#多对多的关系  中间表
app_permission = db.Table("app_permission",db.Column("api_id",db.ForeignKey("api_token.id")),db.Column("permission_id",db.ForeignKey("api_permission.id")))
# api_token表
#存放的是授权密钥,以及授权id
class ApiToken(db.Model):__tablename__ = "api_token"id = db.Column(db.Integer, primary_key=True, autoincrement=True)appid = db.Column(db.String(128), nullable=False)secretkey = db.Column(db.String(128), nullable=False)#通过中间表去创建多对多的关系manage = db.relationship("ApiPermission", secondary=app_permission, backref="token")#存放的是授权的url
class ApiPermission(db.Model):__tablename__ = "api_permission"id = db.Column(db.Integer, primary_key=True, autoincrement=True)url = db.Column(db.String(128), nullable=False)method_type = db.Column(db.String(128), nullable=False)

新增了文件,记得一定要“用到”我们的项目,绑定,运行了没有?
在init文件里加入

from . import user

然后生效到数据库里
terminal

flask --app server:sq_app db migrate
flask --app server:sq_app db upgrade

在Python中,如果你想在不改变业务逻辑源代码的情况下添加额外功能,你可以使用以下几种方法:

使用装饰器:装饰器可以在不改变函数或方法代码的情况下,添加额外的功能。例如,你可以使用装饰器来记录函数执行的时间,或者验证函数的输入。

def timing_decorator(func):  def wrapper(*args, **kwargs):  start = time.time()  result = func(*args, **kwargs)  end = time.time()  print(f"{func.__name__} took {end - start} seconds")  return result  return wrapper  @timing_decorator  
def my_function():  # your code here

使用继承:如果你想要在不改变类的方法的情况下添加额外功能,你可以创建一个新的类,继承自原始类,并在新的类中添加额外的方法。

class OriginalClass:  # original methods here  class NewClass(OriginalClass):  def extra_method(self):  # extra functionality here

使用Mixin:Mixin是一种设计模式,它允许你在不修改类的情况下,将额外的功能添加到类中。你可以创建一个Mixin类,其中包含你想要添加的额外方法,然后让这个类继承自原始类。

class MixinClass:  def extra_method(self):  # extra functionality here  class OriginalClass:  # original methods here  class NewClass(OriginalClass, MixinClass):  pass  # NewClass now has all the methods of OriginalClass and MixinClass

使用AOP(面向切面编程):AOP是一种编程范式,它允许程序员将横切关注点(cross-cutting concerns)从它们所影响的业务逻辑中分离出来。这种范式在处理一些“在哪里执行代码”的问题时特别有用,比如日志记录、事务处理、安全检查等。Python的某些库如Aspectlib、Hybrid等支持这种范式。
使用Monkey Patching:Monkey Patching是一种动态(运行时)修改模块或类的技术。使用这种方法,你可以在不修改源代码的情况下添加或改变功能。然而,这种方法应该谨慎使用,因为它可能会导致代码难以理解和维护。

libs/auth.py

from flask import request
from models.user import ApiToken, ApiPermission
from hashlib import md5
# import timedef auth_required(func):def inner(*args, **kwargs):if api_auth():return func(*args, **kwargs)else:return "认证失败"return inner# api授权认证函数  --  函数返回为真表示认证成功
# 哈希算法 -- md5单向加密
def api_auth():params = request.args  # 客户端url传递过来的参数appid = params.get("appid")salt = params.get("salt")  # 盐值sign = params.get("sign")  # 签名timestamp = params.get("timestamp")  # 时间戳# if time.time() - int(timestamp) > 600:#     return Falseapi_token = ApiToken.query.filter_by(appid=appid).first()if not api_token:return False# 验证有没有此url和方法的权限# http://127.0.0.1:8000/v1/monitor   GET#                                /v1/monitor         getif not has_permission(api_token, request.path, request.method.lower()):return False# 获取数据库里的密钥secretkey = api_token.secretkey# 生成服务端的签名# 可以加上时间戳来防止签名被别人盗取,重复访问# user_sign = appid + salt + secretkeyuser_sign = appid + salt + secretkey ##+ timestampm1 = md5()m1.update(user_sign.encode(encoding="utf-8"))# 判断客户端传递过来的签名和服务端生成签名是否一致if sign != m1.hexdigest():# raise AuthFailExceptionreturn Falseelse:return Truedef has_permission(api_token, url, method):# 客户端请求的方法和url# get/v1/monitormypermission = method + url# 获取此api_token对象的所有url权限all_permission = [permission.method_type + permission.urlfor permission in api_token.manage]# ['get/v1/monitor', 'post/v1/monitor']if mypermission in all_permission:return Trueelse:return False

router/product_view/product_api.py

from libs.auth import auth_requiredclass ProductView(Resource):# @装饰器@auth_requireddef get(self, id = None):

api授权流程
1.客户端向服务端申请授权,服务端向客户端提供appid和secretkey,以及加密算法
2.客户端按照服务端提供的信息、算法,生成签名,请求时发送给服务端
3.服务端收到信息,验证是否成功

客户端请求代码libs/api_auth_clilent.py

import requests
import random
import hashlibdef calculate_sign(appid, salt, secretkey):user_sign = appid + salt +secretkeym1 = hashlib.md5()m1.update(user_sign.encode(encoding='utf-8'))return m1.hexdigest()length_of_string = random.randint(1, 10)
appid = "sc"
salt = "JD"
secretkey = "123456"sign =calculate_sign(appid, salt, secretkey)url = 'http://127.0.0.1:9000/v1/product'
params = {'appid': appid,'salt': salt,'sign': s ign
}
response = requests.get(url, params=params)
if response.status_code == 200:print(response.json())
else:print(f"请求失败,状态码:{response.status_code}")

运行结果:
在这里插入图片描述
为了更安全,可以加入时间戳

注册登录
models/user.py

"""
@date: 2023/9/16
@file: user
@author: Jiangda
@desc: test"""from . import db
from werkzeug.security import generate_password_hash
import datetime#API授权表的模型
#多对多的关系  中间表
app_permission = db.Table("app_permission",db.Column("api_id",db.ForeignKey("api_token.id")),db.Column("permission_id",db.ForeignKey("api_permission.id")))
# api_token表
#存放的是授权密钥,以及授权id
class ApiToken(db.Model):__tablename__ = "api_token"id = db.Column(db.Integer, primary_key=True, autoincrement=True)appid = db.Column(db.String(128), nullable=False)secretkey = db.Column(db.String(128), nullable=False)#通过中间表去创建多对多的关系manage = db.relationship("ApiPermission", secondary=app_permission, backref="token")#存放的是授权的url
class ApiPermission(db.Model):__tablename__ = "api_permission"id = db.Column(db.Integer, primary_key=True, autoincrement=True)url = db.Column(db.String(128), nullable=False)method_type = db.Column(db.String(128), nullable=False)class User(db.Model):__tablename__ = "userdb"id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(128), nullable = False)_password = db.Column("password", db.String(128), nullable=False)role = db.Column(db.Integer, default=0)add_time = db.Column(db.DateTime, default = datetime.datetime.now)# 属性包装装饰器:python内置装饰器# 作用:把方法当作属性一样使用,定义属性之前做一些检测、转换#@property   #自动根据函数名生成两个装饰器 ==》password.setter password.deletedef password(self):return self._password# user.password()  -->print(user.password)@password.setterdef password(self, value):self._password = generate_password_hash(value)@classmethod  #类方法 第一个参数代表类本身def create_user(cls, username, password):user = cls() #创建实例对象user.username = usernameuser.password = password #调用password.setter装饰的函数,强制性要求存hash值db.session.add(user)db.session.commit()

在这里插入图片描述
在这里插入图片描述

接着,对数据进行校验(密码合法性什么的,有专门的库)
pip install wtforms DataRequired, Regexp, ValidationError

forms/user.py

from wtforms import Form, StringField
from wtforms.validators import DataRequired, Regexp, ValidationError
from models.user import Userclass Userform(Form):username = StringField(validators=[DataRequired()])password = StringField(validators=[DataRequired(), Regexp(r'\w{6,18}', message="密码不符合要求")])#     自定义验证器,验证用户名是否唯一
#     自定义检查字段 方法名:validate_你要检查的字段def validate_username(self, value):if User.query.filter_by(username = value.data).first():raise  ValidationError("用户已存在")

修改router/user/user.py(做了数据校验的版本)

from flask import request
from . import user_bp
from flask_restful import Resource, Api
from models.user import User
from libs.response import generate_response
from forms.user import Userformapi = Api(user_bp)class UserRegister(Resource):
# post方法 -- json  /v1/user# # 没做数据校验的版本(如下)# def post(self):#     username = request.json.get("username")#     password = request.json.get("password")##     if username is not None:#         if password is not None:#             new_user = User.create_user(username, password)#             return generate_response(msg="register success!")#         else:#             return generate_response(msg="register fail!", code=20)#     else:#         return generate_response(msg="no username", code=21)#做了数据校验的版本def post(self):#try:data = request.jsonform = Userform(data=data)if form.validate():User.create_user(username = data.get("username"),password = form.password.data)return  generate_response(msg="注册成功", code=0)else:return generate_response(code=1, msg=form.errors)#except:#return generate_response(code=1, msg="注册失败!")api.add_resource(UserRegister,"/user")

在这里插入图片描述

相关文章:

【自学开发之旅】Flask-会话保持-API授权-注册登录

http - 无状态-无法记录是否已经登陆过 #会话保持 – session cookie session – 保存一些在服务端 cookie – 保存一些数据在客户端 session在单独服务器D上保存,前面数个服务器A,B,C上去取就好了,业务解耦。—》》现在都是基于token的验证。 以上是基…...

数据结构与算法--排序算法复习

目录 1.三种常见的简单排序: 1.1冒泡排序 1.2 选择排序 1.3 插⼊排序 2 常见高级排序算法 2.1 希尔排序 2.2 快速排序 2.3 归并排序 2.4计数排序 先上结论: 1.三种常见的简单排序: 1.1冒泡排序 1.⾸先在未排序数组的⾸位开始&#…...

python随手小练1

题目: 使用python做一个简单的英雄联盟商城登录界面 具体操作: print("英雄联盟商城登录界面") print("~ * "*15 "~") #找其规律 a "1、用户登录" b "2、新用户注册" c "3、退出系统&quo…...

gym_unity学习笔记

最近学了一段时间gym_unity,把一些资料留在这里 实例 实例gym_unity训练RollerBall:https://blog.csdn.net/alibutter/article/details/120908687实例gyn_unity训练3DBall:https://zhuanlan.zhihu.com/p/554927641?utm_id0 源码&#xff1…...

(三十)大数据实战——HBase集成部署安装Phoenix

前言 Phoenix 是一个开源的分布式关系型数据库查询引擎,它基于 Apache HBase构建。它提供了在 Hadoop 生态系统中使用 SQL查询和事务处理的能力。本节内容我们主要介绍一下Hbase如何集成部署安装Phoenix服务工具,并集成hive框架,能够快速、灵…...

【Python基础】S01E03 元组

P01S03 元组 定义元组元组无法修改定义一个元素的元素 修改元组变量方案一:关联新元组方案二:转换为列表 列表是可修改的,对于处理网站的用户列表或游戏中的角色列表至关重要。然而我们有时候需要创建一系列不可修改的元素,元组可…...

【算法-双指针思想】

双指针思想 双指针法(快慢指针法): 通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。 定义快慢指针 快指针: 寻找新数组的元素 ,新数组就是不含有目标元素的数组 慢指针: 指向更新 新数组下…...

uni-app实现点击复制按钮 复制内容

注意:uni.setClipboardData({})里面的data参数必须是字符串类型这个是大坑 第一种 <view>{{orderId}}</view> //复制的内容 <button click"copy(orderId)">复制</button>copy(value) {uni.setClipboardData({data: value , // 这里是个坑接…...

Qt5开发及实例V2.0-第十四章-Qt多国语言国际化

Qt5开发及实例V2.0-第十四章-Qt多国语言国际化 第14章 Qt 5多国语言国际化14.1 基本概念14.1.1 国际化支持的实现14.1.2 翻译工作&#xff1a;“*.qm”文件的生成 14.2 【实例】14.2.1 简单测试14.2.2 选择语言翻译文字 本章相关例程源码下载1.Qt5开发及实例_CH1401.rar 下载2.…...

嵌入式网络接口之MAC芯片与PHY芯片

目录 0. 参考文档 1.嵌入式网络接口简介 2.嵌入式网络硬件架构方案 2.1 SOC内未集成MAC芯片 2.2 SOC内集成MAC芯片 2.3 主流方案总结 2.3 参照实际网卡的说明 3.MII/RMII及MDIO接口 3.1 MII 3.2 RMII 3.3 MDIO 0. 参考文档 网卡构造&#xff1a;MAC与PHY的关系&…...

在华为云服务器上CentOS 7安装单机版Redis

https://redis.io/是官网地址。 点击右上角的Download。 可以进入https://redis.io/download/——Redis官网下载最新版的网址。 然后在https://redis.io/download/页面往下拉&#xff0c;点击下图超链接这里。 进入https://download.redis.io/releases/下载自己需要的安装…...

01_Bootstrap基础组件01

1 什么是 Bootstrap&#xff1f; Bootstrap&#xff0c;来自 Twitter&#xff0c;是目前很受欢迎的前端框架。Bootstrap 是基于 HTML、CSS、JavaScript 的&#xff0c;它简洁灵活&#xff0c;使 Web 开发更加快捷。它对 HTML、CSS 和 JavaScript 进行了封装&#xff0c;使它们…...

Java:OGNL对象图导航语言基本使用示例

OGNL是Object Graphic Navigation Language(对象图导航语言) 文档 https://commons.apache.org/proper/commons-ognl/language-guide.htmlhttps://github.com/orphan-oss/ognlhttps://ognl.orphan.software/developer-guide 引入依赖 <!-- https://mvnrepository.com/ar…...

中科院预警名单

2023年预警名单 (fenqubiao.com) 如果论文投稿到中国科学院预警期刊,可能会面临以下情况: 1. 预警期刊一般审稿周期长,容易出现迟迟不见回音的情况。 2. 这类期刊的学术质量参差不齐,接受论文的学术标准可能不严格。 3. 预警期刊发表论文的学术影响力比较有限,不容易为作者…...

Qt QCustomPlot介绍

介绍 主要介绍qcustomplot及其用法 最新版本:QCustomPlot Patch Release 2.1.1//November 6, 2022 下载:https://www.qcustomplot.com/index.php/download 官网:https://www.qcustomplot.com/index.php 简单使用 mainwindow.h /**************************************…...

什么是CORS(跨源资源共享)?如何解决前端中的CORS问题?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ CORS&#xff08;跨源资源共享&#xff09;⭐ 解决前端中的CORS问题的方法⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为…...

C 初级学习笔记(基础)

目录 1.预处理器指令 预定义宏 预处理器运算符 &#xff08;\&#xff09; 参数化的宏 头文件 .h 引用头文件操作 2.函数&#xff08;标识符&关键字&运算符&#xff09;存储类 函数参数 a. 标识符&关键字 b. 运算符&#xff08;算术、关系、逻辑、位、赋…...

Nodejs 相关知识

Nodejs是一个js运行环境&#xff0c;可以让js开发后端程序&#xff0c;实现几乎其他后端语言实现的所有功能&#xff0c;能够让js与其他后端语言平起平坐。 nodejs是基于v8引擎&#xff0c;v8是Google发布的开源js引擎&#xff0c;本身就是用于chrome浏览器的js解释部分&#…...

【vue+elementUI】输入框样式、选择器样式、树形选择器和下拉框样式修改

输入框样式、选择器样式和下拉框样式修改 1、输入框和选择器的样式修改&#xff1a;2、下拉弹框样式A. 选择器的下拉弹框样式修改B. 时间选择器的下拉弹框样式修改C. vue-treeselect树形下拉框样式 1、输入框和选择器的样式修改&#xff1a; 写在style中不能加scoped&#xff0…...

JavaScript - canvas - 放大镜

效果 示例 项目结构&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>放大镜</title><style type"text/css">div {width: 200px;height: 200px;display: inline-bl…...

PY32F003F18之输入捕获

输入捕获是定时器的功能之一&#xff0c;配合外部引脚&#xff0c;捕获脉宽时间或采集周期。 CPU中的定时器最基本的功能就是计数功能&#xff0c;其次是输入捕获(IC)&#xff0c;再次就是比较输出(OC)&#xff0c;还有就是使用引脚对外部时钟进行计数&#xff0c;触发信号捕捉…...

科目三基础四项(一)

​ 第一天&#xff0c;基础操作&#xff0c;仪表&#xff0c;方向&#xff0c;挡位 按照模块来 1、方向盘两手在两侧 ​ 编辑 转向时的角度&#xff0c;只用&#xff1a;向左540&#xff0c;向右180 向左打和向右打的角度要抵消&#xff0c;回正 掉头向左打满再回 注意…...

C语言入门Day_24 函数与指针

目录 前言&#xff1a; 1.指针和数组 2.函数和指针 3.易错点 4.思维导图 前言&#xff1a; 我们知道数组是用来存储多个数据的&#xff0c;以及我们可以用指针来指向一个变量。那么我们可以用指针来指向一个数组中的数据么&#xff1f; 指针除了可以像指向一个变量一样指…...

9月21日,每日信息差

今天是2023年9月21日&#xff0c;以下是为您准备的14条信息差 第一、谷歌高管已经广泛讨论了在2027年之前将博通作为人工智能芯片供应商的可能性 第二、清华系团队宣布研发出千亿参数“制药版ChatGPT”&#xff0c;覆盖药物立项、临床前研究、临床试验的各阶段&#xff0c;作…...

【FAQ】安防监控系统/视频云存储/监控平台EasyCVR服务器解释器出现变更该如何修改?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...

Python手写人脸识别

Python手写人脸识别 引言 人脸识别是一种通过计算机视觉和模式识别技术来识别和验证人脸的技术。Python是一种广泛使用的编程语言,它提供了许多强大的库和工具来实现人脸识别。 在Python中,可以使用多种方法来实现人脸识别,包括基于特征提取的方法、基于深度学习的方法等…...

我的Qt作品(19)使用Qt写一个轻量级的视觉框架---第2章,仿海康VM实现思维导图拖拽方式的算法流程图

上次写的第1章介绍了主界面的设计。 https://blog.csdn.net/libaineu2004/article/details/130277151 本次是第2章&#xff0c;主要介绍流程图的运行。 目前市面上视觉框架很多&#xff0c;主要有列表图方式和流程图方式。海康VM的流程图方式比较受用户的喜爱和欢迎&#xf…...

仿写Timi记账

项目仿照Timi记账&#xff0c;本 APP 仅用作学习&#xff0c;如有侵权联系删除&#xff0c;项目地址&#xff1a;Timi记账 TIMI记账项目 简单功能对于tableview向上延伸部分采用了insertSubview形式&#xff1a;添加特殊字体添加.ttf文件获取plist文件数据 计算器功能说明简单逻…...

Java语言实现 比较两个Date日期的先后

在 Java 中&#xff0c;可以使用 Date 类的 compareTo() 方法或 before()、after() 方法来比较两个 Date 类型的日期的先后顺序。 使用 compareTo() 方法&#xff1a; Date date1 ...; // 第一个日期 Date date2 ...; // 第二个日期int result date1.compareTo(date2); if (…...

el-table 指定层级展开

先来看看页面默认全部展开时页面的显示效果&#xff1a;所有节点被展开&#xff0c;一眼望去杂乱无章&#xff01; 那么如何实现只展开指定的节点呢&#xff1f;最终效果如下&#xff1a;一眼看去很舒爽。 干货上代码&#xff1a; <el-table border v-if"refreshTabl…...

wordpress扫码支付下载/最近的新闻热点

啤酒每罐2.3元&#xff0c;饮料每罐1.9元。小明买了若干啤酒和饮料&#xff0c;一共花了82.3元。 我们还知道他买的啤酒比饮料的数量少&#xff0c;请你计算他买了几罐啤酒。 注意&#xff1a;答案是一个整数。请通过浏览器提交答案。 不要书写任何多余的内容&#xff08;例如&…...

网站上可以做直播吗/网络推广与优化

这里阅读的php版本为PHP-7.1.0 RC3&#xff0c;阅读代码的平台为linux ZTS 我们会看到文章中有很多地方是: #ifdef ZTS # define CG(v) ZEND_TSRMG(compiler_globals_id, zend_compiler_globals *, v) #else # define CG(v) (compiler_globals.v) extern ZEND_API struct _zend…...

淘宝联盟做独立网站/谷歌浏览器官网

本文在我的微信公众号&#xff1a;hongyangAndroid原创首发。很多时候&#xff0c;由于迭代周期有限&#xff0c;开发任务多、时间紧&#xff0c;导致很多产品基本没有单元测试&#xff0c;从而也导致很多同学这块都是盲区。其实我对测试接触也非常少&#xff0c;所以深度方面是…...

天津b2b网站建设公司价格/免费域名申请

一、 MySQL 数据库 分页查询MySQL数据库实现分页比较简单&#xff0c;提供了 LIMIT函数。一般只需要直接写到sql语句后面就行了。LIMIT子 句可以用来限制由SELECT语句返回过来的数据数量&#xff0c;它有一个或两个参数&#xff0c;如果给出两个参数&#xff0c; 第一个参数指定…...

做seo网站空间/百度快照怎么打开

查看贺老师更多课程… 【关于Raptor】    “没有思路”&#xff0c;这是不少程序设计初学者挂在嘴边的问题。在用编程解决问题的过程中&#xff0c;让自己具备编程的思维&#xff0c;这是我一直倡导的做法&#xff0c;不少同学坚持了&#xff0c;也找到了感觉。   有没…...

自己如何制作一个软件/手机seo排名

图 1&#xff1a;集成安全测试的工作原理。 如何使用集成安全测试使用Selenium查找 XSS 实例 XSS 是 Web 应用程序的常见安全问题&#xff0c;也是OWASP Top 10 上的一个持久问题。简单地说&#xff0c;就是一个用户在另一个页面上执行一个脚本。这通常是通过简单地注入脚本标…...