Flask接口签名sign原理与实例代码浅析

目录
  • 作用
  • 原理
  • 问题
    • 问题1
      • 解决办法
    • 问题2
      • 解决办法
      • 代码

觉得废话多的话,可以直接看代码

作用

防止有人不停的刷接口,对接口作限制

比如说,登录接口,按道理说,应该只有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

到此这篇关于Flask接口签名sign原理与实例代码浅析的文章就介绍到这了,更多相关Flask接口签名sign内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python+flask实现restful接口的示例详解

    目录 1.第一个实例:HelloWorld 2.Post 方法 3.Get 方法 4.通过变量设置动态url 1.第一个实例:HelloWorld 1.编写python代码 from flask import Flask app=Flask(__name__) @app.route('/HelloWorld') def hello_world(): return "Hello World!" if __name__ == "__main__": app.run(ho

  • python+flask编写接口实例详解

    环境:Pycharm :其他环境:安装Anaconda 最近在做一个小型项目练手,涉及到大量的IP和相关数据处理,所以选用了Python来处理数据,但是处理完怎么给前端调用呢,今天这篇就是在Python方便地处理完数据后以接口形式把数据返回给前端. flask就是使用Python编写接口实例的关键库,先配置项目: ①(这一步可以使用Python默认解释器,但是后续安装库可能还需要配置,建议使用Anaconda)首先打开PyCharm,在file->settings->Project->p

  • python+flask编写一个简单的登录接口

    在学习接口测试的时候往往会因为没有实际操作的接口进行测试而烦恼,这里教大家自己编写两个接口用于学习接口测试 1.编写一个登录的接口 2.在pycharm运行 3.使用apipost进行登录接口测试 输入url和参数值进行访问,访问成功. 4.在pycharm查看是否正常进行访问 5.在编写一个需要登录返回的token直接访问的查询接口 6.运行登录和查询两个接口 7.使用apipost进行登录和查询的接口测试 首先进行登录的接口测试获取返回的token 使用登录返回的token值进行查询的接口测

  • Python接口传输url与flask数据详解

    周五下午,作为小白太痛苦了,这两天一直在做一件事,如下: 使flask接口中的函数执行的同时,向指定的url传递数据(我甚至不知道怎么描述这个问题).大概的函数结构使这样的: app1 = Flask('app1') @app1.route('/', methods=["POST"]) def pic(): data = request.get_data() # 获取参数字典 # func1在执行过程中会保存图并对图片进行处理 # *需求是在func1把图保存后立即向指定的url传输图

  • python 详解如何写flask文件下载接口

    简述 写一个简单的flask文件下载接口. 依赖 flask.gevent 代码 不废话上代码. #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Sat Oct 23 19:53:18 2021 @author: huyi """ from flask import Flask, request, make_response, send_from_directory fr

  • 基于python和flask实现http接口过程解析

    为什么要做这个? mock 第三方服务时,需要使用,另外包括自身开发,有时也会用到python #!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Fri Jun 12 18:52:42 2020 @author: ansonwan """ from flask import Flask, request, jsonify import json app = Flask(__

  • Flask接口签名sign原理与实例代码浅析

    目录 作用 原理 问题 问题1 解决办法 问题2 解决办法 代码 觉得废话多的话,可以直接看代码 作用 防止有人不停的刷接口,对接口作限制 比如说,登录接口,按道理说,应该只有app会请求这个接口 但是,如果有人抓取app的请求,就会得到登录接口的地址和请求参数 如果他写了个脚本,不断的访问登录接口,去测登录名密码,那么有些有些用户的密码策略过于简单,是很容易被试出来的 所以,接口签名就是专门用来限制这个的,只有app(自己人)才能通过校验 原理 1.服务器和app,各自存储一个相同的秘钥 2.

  • 使用Python做垃圾分类的原理及实例代码

    0 引言 纸巾再湿也是干垃圾?瓜子皮再干也是湿垃圾??最近大家都被垃圾分类折磨的不行,傻傻的你是否拎得清?

  • 使用Python做垃圾分类的原理及实例代码附源码

    0 引言 纸巾再湿也是干垃圾?瓜子皮再干也是湿垃圾??最近大家都被垃圾分类折磨的不行,傻傻的你是否拎得清?

  • Java通过接口实现匿名类的实例代码

    复制代码 代码如下: package com.chase.test; /** * 通过接口实现匿名类的实例 *  * @author Chase *  * @date 2013-10-18 下午04:28:17  * * @version V1.0 */interface I1 {    void print();    void eat();} public class AnonymousClass { public static String excute(I1 c){        Sys

  • Java 方法签名详解及实例代码

    java 方法签名,我想做java 开发的朋友也知道,方法签名的重要性,是方法重载的一个比较好的解释,尤其是在后续优化方面,这里记录下,有看到的朋友也可看下, 方法签名的意义 对于同名不同类.同类不同名的方法,方法签名的意义并不是很大,但是对于重载方法来说,方法签名的意义就十分巨大了.由于重载方法之间的方法名是相同的,那么我们势必要从构成方法的其他几个要素中找到另一个要素与方法名组成能够唯一标示方法的签名,方法体当然不予考虑.那么就是形参列表和返回值了,但是由于对于调用方法的人来说,方法的形参数

  • jQuery on()方法绑定动态元素的点击事件实例代码浅析

    之前就一直受这个问题的困扰,在jQuery1.7版本之后添加了on方法,之前就了解过,其优越性高于live(),bind(),delegate()等方法,在此之前项目中想用这个来测试结果发现,居然动态生成的标签点击了没反应,而live方法却能够支持,于是乎到处查资料,问网友,结果找了好久在一篇文章中终于找到了答案... jQuery 使用on绑定动态生成的元素时,不能直接用该对象操作,而是选择其非动态生成的父节点然后再找到本身才能达到效果.大家看看源码就知道了.生成的按钮基数项on方法点击无效l

  • PHP文件下载实例代码浅析

    文件下载的功能对一个网站而言基本上是必备的了,今天就来看看PHP是如何实现文件下载的吧. 无控制类型 这里说的无控制类型是指 没有添加PHP代码控制的资源可以被直接下载的那些类型.一般而言,压缩文件.rar; 音视频文件:..avi等等也可以被直接下载.但是音频和mp4则会直接被浏览器解析播放. 如下图: .avi文件 .rar文件 .mp4,MP3,图片等会被直接解析 核心代码 使用php代码控制文件的下载合适很简单的.我们住需要很少的代码便可以完成如此复杂的工作. 类型 // 使用basen

  • Java方法签名的获取实例代码

    本文研究的主要是Java方法签名的获取,下面是具体实现实例. 实例代码: package com.yunshouhu; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Collection; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.

  • Vue+Springboot实现接口签名的示例代码

    1.实现思路 接口签名目的是为了,确保请求参数不会被篡改,请求的数据是否已超时,数据是否重复提交等. 接口签名示意图 客户端提交请求时,将以下参数按照约定签名方式进行签名,随后将参数和签名一同提交服务端: 1.请求头部分(header) appid:针对不同的调用方分配不同的appid. noce:请求的流水号,防止重复提交. timestamp:请求时间戳,验证请求是否已超时失效. 2.数据部分 Path:按照path中的参数将所有key=value进行拼接. Query:按照所有key=va

  • 微信小程序 request接口的封装实例代码

    微信小程序 request接口的封装实例代码 小程序request接口的封装(本质上是对request回调函数再次回调) module.exports.getData = function (url) { var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var method = arguments.length > 2 && arguments[

随机推荐