Flask接口签名sign原理与实例代码浅析
作者:高冷的王哈哈 发布时间:2023-06-21 23:18:13
觉得废话多的话,可以直接看代码
作用
防止有人不停的刷接口,对接口作限制
比如说,登录接口,按道理说,应该只有app会请求这个接口
但是,如果有人抓取app的请求,就会得到登录接口的地址和请求参数
如果他写了个脚本,不断的访问登录接口,去测登录名密码,那么有些有些用户的密码策略过于简单,是很容易被试出来的
所以,接口签名就是专门用来限制这个的,只有app(自己人)才能通过校验
原理
1.服务器和app,各自存储一个相同的秘钥
2.app请求时,把传的参数用秘钥进行加密,生成一个sign签名,一同传递过去
3.服务器接到请求后,也会对传递的参数进行加密,也生成一个sign签名,拿服务器生成的sign和接口请求的sing比对一下,如果相同,那么就可以证明,是自己人请求的,就予以放行
因为这个秘钥,只有自己人才会有,同样的秘钥生成的sign签名,肯定是一模一样的
这个秘钥,一般是开发的时候,线下给到app开发,集成编译到app里面的
问题
举例,app和服务器,各自保存了一个秘钥,进行签名验证
1.app请求登录接口,账号名为abcd,密码为123456,
2.app对账户名和密码用秘钥加密生成签名,去请求登录接口
3.服务器收到请求,对账号名和密码也用秘钥加密生成签名,对比发现签名一致,然后予以通过
4.请求成功
问题1
但是,如果下次app还去请求登录的时候,生成的签名,是不是还是一模一样?
因为都是对账号和密码加密生成签名,那么只要账号和密码不变,那么生成的签名肯定是一模一样的
那如果坏人直接抓包拿到签名、账号和密码,是不是他也可以仿造登录请求,要知道,服务器只接受请求,他是分辨不出来的
所以,即使是相同的账号和密码,也要保证,每次的签名都不一致
解决办法
在对账号和密码进行加密的时候,生成当前时间的时间戳,一起加密,这样就保证了每次生成的签名都一样了
传递参数的时候,也需要把加密用的时间戳一同传递过去,因为请求时候延迟的,服务器并不知道你是哪个时间进行加密的
那么现在生成签名和请求的步骤就是:
1.app先对账号、密码、时间戳,用秘钥进行加密得到签名
2.app请求登录接口,传参:账号、密码、时间戳、签名
问题2
那么问题又来了,跟刚才的问题一样,如果有人抓包,得到账号、密码、时间戳、签名,然后去伪造请求,是不是服务器还会通过?
只要账号、密码、时间戳不变化,那么生成的签名,还是一模一样的。
解决办法
服务器对时间戳进行校验,与当前时间不能相差10秒
这样就保证了,这个签名的有效期只有10秒,过了10秒后,就失效了
如果想要新的签名,那么就需要用新的时间戳了
代码
如果需要传递很多参数的时候,还需要对参数进行排序后再加密,要不然app和服务器用了不一样的字符串加密,校验还是会失败的
import hashlib
import time
salt = 'nx24Tej@R4gWVCopJkjHWjBo@n58LdQ5' # 盐, 加密生成签名的秘钥
def validate_sign(sign, ts, **kwargs):
"""时间戳有效期10秒,排序顺序为:盐+时间戳+按照字母排序的参数的值"""
# 首先判断ts时间戳,有没有超过10秒有效期
now_ts = int(time.time())
if now_ts - int(ts) > 10:
return False
# 对字典中的键进行排序
sort_dict = sorted(kwargs.items(), key=lambda x: x[0])
# 按照排序拿出值,拼接成字符串,然后加密生成签名
s = salt + str(ts)
for key, value in sort_dict:
s += str(value)
# 使用sha256加密,与app也要约定好加密方式
new_sign = hashlib.sha256(s.encode('utf-8')).hexdigest()
# 比对签名是否一致
if sign == new_sign:
return True
return False
validate_sign(1, int(time.time()), phone="15555555555", password="123456")
# 排序后的字符串:nx24Tej@R4gWVCopJkjHWjBo@n58LdQ5167541269212345615555555555
# 生成的签名: d87f2833c1f6a1d0d3c67bafdeb0965b0503385dce615662229b27333c9963f7
来源:https://blog.csdn.net/w1054230914/article/details/128872847
猜你喜欢
- 1.为什么要跨平台编程?双平台编程或多平台编程,只是为提供更好开发更兼容的解决方案的一种手段,编程时服务于产品和客户的,也是因地制宜。先安装
- 对于初学者来说,找到一个好的框架来学习或者项目开发都是非常有必要的,而当你有一定开发经验后,你应该选择适合当前业务需要的框架。我这里并不想探
- import siximport timeit#查找任何特定代码执行的确切时间from ecdsa.curves import curves
- 为什么需要线程池呢? 设想一下,如果我们使用有任务就开启
- 安装pip install requests发送网络请求import requestsr=requests.get('http://
- 1、确认框架中安装了第三方alibabacoud控件实现代码如下上传过程中遇到任务问题,可以进行留言<?php namespace A
- 2个简单的代码,帮你实现word的导出和word的读取功能一:导出word,word中的内容为代码:from docx import Doc
- 下面的代码是日期函数的一些简单运用,应该不用解释,生成当月的日历,当然你可以根据实际情况进行扩充!效果图:<%@LANGUAGE=&q
- Python编程中对于某些需要重复调用的程序,可以使用函数进行定义,基本形式为:def 函数名(参数1, 参数2, ……, 参数N):执行语
- 用 docx 模块读取 Worddocx 安装cmd 中输入pip install python-docx 即可安装 docx 模块docx
- 本文实例讲述了Python实现求最大公约数及判断素数的方法。分享给大家供大家参考。具体实现方法如下:#!/usr/bin/env pytho
- Oracle游标分为显示游标和隐式游标。显示游标(Explicit Cursor):在PL/SQL程序中定义的、用于查询的游标称作显示游标。
- 1 引言各位朋友大家好,欢迎来到月来客栈。今天要和大家介绍的内容是如何在Pytorch框架中对模型进行保存和载入、以及模型的迁移和再训练。一
- 本文实例讲述了Python实现读取TXT文件数据并存进内置数据库SQLite3的方法。分享给大家供大家参考,具体如下:当TXT文件太大,计算
- Django 中自带了 sitemap框架,用来生成 xml 文件Sitemap(站点地图)是通知搜索引擎页面的地址,页面的重要性,帮助站点
- 测试驱动开发(TDD)是一个迭代的开发周期,强调编写实际代码之前编写自动化测试。这个过程很简单: 先编写
- mysql数据库没有增量备份的机制,当数据量太大的时候备份是一个很大的问题。还好mysql数据库提供了一种主从备份的机制,其实就是把主数据库
- numpy.ndarray添加元素平常使用的比较多的是list,在list后面添加元素直接是data_list = []data_list.
- 本文实例讲述了PHP解析xml格式数据工具类。分享给大家供大家参考,具体如下:class ome_xml { /**  
- 本文为大家分享了python实现图书馆研习室自动预约的具体代码,供大家参考,具体内容如下简介现在好多学校为学生提供了非常良好的学习环境,通常