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

开放平台设计之接口签名认证

前言

当前时代,数据是王道!当我们自己的平台有了足够大的数据量,就有可能诞生一个开放平台宫第三方分析、使用。那么我们怎么去实现对外部调用接口的控制与鉴权呢?这是我们今天的重点——接口签名认证!!!

签名认证

开放平台会为每一位注册用户分配一个对应账户API KEY和秘钥API SECRET。我们为了保证接口的安全性,用户在每次接口的调用都需要上传一个所谓的签名(基于API KEYAPI SECRET获取)

签名认证步骤:

  1. 首先生成一个Unix时间戳timestamp,时间精确到毫秒【即1970年1月1日(UTC/GMT的午夜)开始所经过的毫秒数】;
  2. 生成随机数nonce(注:目前定义的是32位的,可以通过随机数工具类生成) ;
  3. 1)将timestamp、nonce、API_KEY 这三个字符串依据“字符串首位字符的ASCII码”进行升序排列(排序过程中若出现ASCII码值相同的情况,则依次递增对下一位进行比较)(这种排序,”也就是俗称的字典序“),并将排序后的结果拼接成为一个字符串join_str;
    2)接下来在用API_SECRET对上面生成这个字符串join_str做hmac-sha256 签名,并且以16进制编码,得到signature
  4. 将上述得到的timestampnonce,signature,与 API_KEY按照 #{k}=#{v}并以 ',' 为区分拼接在一起形成新的字符串,这就是要返回签名认证字符串authorization;
  5. 当完成以上4步,我们就可以获取最终的签名认证字符串了。调用接口时,将通过签名认证步骤得到的值authorization 传给HTTP HEADER的Authorization对应的值;请求体部分按照相对应文档请求参数说明正确填写,正常发送请求,即可完成一次接口调用。

下面以java代码举例:

假设 API_KEY = "233453f1d1eb4eb5a5ad9c8dac0d02cc";
API_SECRET = "444af44cd3a247c594438fb60d7b1d52";

1. 获得timestamp(unix时间戳),返回timestamp :"1633431976787"

实现方式:

 String timestamp = Long.toString(System.currentTimeMillis()); 

2. 获得随机nonce,返回nonce: "3isQFsTjsnNOLvIPXhf3HlW17WSfQqp9"

可用下面方式实现:

String nonce = RandomStringUtils.randomAlphanumeric(32);

3.将timestamp、nonce、API_KEY 这三个字符串依据“字符串首位字符的ASCII码”进行升序排列(排序过程中若出现ASCII码值相同的情况,则依次递增对下一位进行比较),并join成一个字符串,返回join_str:"1633431976787233453f1d1eb4eb5a5ad9c8dac0d02cc3isQFsTjsnNOLvIPXhf3HlW17WSfQqp9"

可用下面方式实现:

public static String genOriString(String timestamp,String nonce,String API_KEY){ArrayList<String> beforesort = new ArrayList<String>();beforesort.add(API_KEY);beforesort.add(timestamp);beforesort.add(nonce);Collections.sort(beforesort, new SpellComparator());StringBuffer aftersort = new StringBuffer();for (int i = 0; i < beforesort.size(); i++) {aftersort.append(beforesort.get(i));}String join_str = aftersort.toString();return join_str;}

4. 用API_SECRET对join_str做hmac-sha256签名,且以16进制编码,返回signature:"7d37d14406323f0ab30d1d4db1e7f2eb27abac42f3de00d619025108fa6cd5e4"

可用下面方式实现:

public static String genEncryptString(String join_str, String API_SECRET){Key sk = new SecretKeySpec(API_SECRET.getBytes(), "HmacSHA256");Mac mac = Mac.getInstance(sk.getAlgorithm());mac.init(sk);final byte[] hmac = mac.doFinal(join_str.getBytes());//完成hmac-sha256签名StringBuilder sb = new StringBuilder(hmac.length * 2);Formatter formatter = new Formatter(sb);for (byte b : hmac) {formatter.format("%02x", b);}String signature = sb.toString();//完成16进制编码return signature;}

5. 将上述的值按照 #{k}=#{v} 并以 ',' join在一起,返回签名认证字符串:
"key=2371d3f1d1eb4eb5a5ad9c8dac0d02cc,timestamp=1638431976741,nonce=3isWSsTjsnNOLvIPXhf3HlW17WSfQqp9,signature=7d37d14406323f0ab30d1d4db1e7f2eb27abac42f3de00d619025108fa6cd5e4"

可用下面方式实现:

public static String genauthorization(String API_KEY, String timestamp, String nonce, String signature){String authorization = "key=" + API_KEY+",timestamp=" + timestamp+",nonce=" + nonce+",signature=" + signature;return authorization;}

6. 将该签名认证字符串赋值给HTTP HEADER 的 Authorization 中,完成一次接口访问。

DEMO

pom文件中添加一下支持

     <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpmime</artifactId><version>RELEASE</version><scope>compile</scope></dependency>

具体实现代码:


import java.util.Comparator;public class SpellComparator implements Comparator<Object> {public int compare(Object o1, Object o2) {try{String s1 = new String(o1.toString().getBytes("GB2312"), "ISO-8859-1");String s2 = new String(o2.toString().getBytes("GB2312"), "ISO-8859-1");return s1.compareTo(s2);}catch (Exception e){e.printStackTrace();}return 0;}
}
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Formatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.http.client.ClientProtocolException;public class GenerateString {// 开放平台注册获取id(API KEY)public static final String id = "22bfe9745135";// 开放平台注册获取密钥(API SECRET)public static final String secret = "19fbdc10";private static final String HASH_ALGORITHM = "HmacSHA256";static String timestamp = Long.toString(System.currentTimeMillis());static String nonce = RandomStringUtils.randomAlphanumeric(32);public static String genOriString(String api_key){ArrayList<String> beforesort = new ArrayList<String>();beforesort.add(api_key);beforesort.add(timestamp);beforesort.add(nonce);Collections.sort(beforesort, new SpellComparator());StringBuffer aftersort = new StringBuffer();for (int i = 0; i < beforesort.size(); i++) {aftersort.append(beforesort.get(i));}String OriString = aftersort.toString();return OriString;}public static String genEncryptString(String genOriString, String api_secret)throws SignatureException {try{Key sk = new SecretKeySpec(api_secret.getBytes(), HASH_ALGORITHM);Mac mac = Mac.getInstance(sk.getAlgorithm());mac.init(sk);final byte[] hmac = mac.doFinal(genOriString.getBytes());StringBuilder sb = new StringBuilder(hmac.length * 2);@SuppressWarnings("resource")Formatter formatter = new Formatter(sb);for (byte b : hmac) {formatter.format("%02x", b);}String EncryptedString = sb.toString();return EncryptedString;}catch (NoSuchAlgorithmException e1){throw new SignatureException("error building signature, no such algorithm in device "+ HASH_ALGORITHM);}catch (InvalidKeyException e){throw new SignatureException("error building signature, invalid key " + HASH_ALGORITHM);}}public static String genHeaderParam(String api_key, String api_secret) throws SignatureException{String GenOriString = genOriString(api_key);String EncryptedString = genEncryptString(GenOriString, api_secret);String HeaderParam = "key=" + api_key+",timestamp=" + timestamp+",nonce=" + nonce+",signature=" + EncryptedString;System.out.println(HeaderParam);return HeaderParam;}public static void main(String[] args) throws ClientProtocolException, IOException, SignatureException{String s = genHeaderParam(id, secret);System.out.println(s);}
}

好了,今天关于开放平台之接口认证鉴权就到这里。

欢迎大家点击下方卡片关注《coder练习生》

相关文章:

开放平台设计之接口签名认证

前言 当前时代&#xff0c;数据是王道&#xff01;当我们自己的平台有了足够大的数据量&#xff0c;就有可能诞生一个开放平台宫第三方分析、使用。那么我们怎么去实现对外部调用接口的控制与鉴权呢&#xff1f;这是我们今天的重点——接口签名认证&#xff01;&#xff01;&a…...

Vue自创插件发布到npm以及使用方法

Vue自创插件发布到npm以及使用方法 目标&#xff1a;创建my-popup-selector下拉框组件&#xff0c;并发布到npm&#xff0c;效果如下图&#xff1a; 禁用时样式&#xff1a; ①创建vue项目&#xff1a; my-popup-selector ②项目目录结构截图如下&#xff1a; ③在项目根目录…...

合成孔径雷达干涉测量InSAR数据处理、地形三维重建、形变信息提取、监测等实践技术

合成孔径雷达干涉测量&#xff08;Interferometric Synthetic Aperture Radar, InSAR&#xff09;技术作为一种新兴的主动式微波遥感技术&#xff0c;凭借其可以穿过大气层&#xff0c;全天时、全天候获取监测目标的形变信息等特性&#xff0c;已在地表形变监测、DEM生成、滑坡…...

Java刷题,蓝桥杯省赛第十二届(第一场)4-------------6

4、相乘题目本题总分&#xff1a;10 分【问题描述】小蓝发现&#xff0c;他将 1 至 1000000007 之间的不同的数与 2021 相乘后再求除以1000000007 的余数&#xff0c;会得到不同的数。小蓝想知道&#xff0c;能不能在 1 至 1000000007 之间找到一个数&#xff0c;与 2021 相乘后…...

Docker Cgroups——Docker 资源限制背后的技术原理

Docker Cgroups——Docker 资源限制背后的技术原理虽然在容器内部进程只能看到“掩饰”过的视图&#xff0c;但是在宿主机上&#xff0c;它就是一个普通的进程&#xff0c;与其他所有进程之间是平等竞争的关系。这就意味着虽然表面上被隔离了&#xff0c;但它实际上在与其他进程…...

十四. MySQL 锁相关

目录一. MySQL 锁基础Mysql 锁分类二. InnoDB 下的锁增删改查操作时底层的加锁处理表级锁1. 意向锁2. AUTO-INC锁id不连续对主从同步的影响3. 其它表锁行锁分析1. 记录锁 Record Locks2. 间隙锁 Gap Locks3. 临键锁 Next-Key Locks4. 插入意向锁5. 隐式锁6. 加锁算法InnoDB 行锁…...

ModStartBlog v7.0.0 网站简单统计,支持博客分享

ModStart 是一个基于 Laravel 模块化极速开发框架。模块市场拥有丰富的功能应用&#xff0c;支持后台一键快速安装&#xff0c;让开发者能快的实现业务功能开发。 系统完全开源&#xff0c;基于 Apache 2.0 开源协议。 功能特性 丰富的模块市场&#xff0c;后台一键快速安装 …...

【C语言蓝桥杯每日一题】—— 递增序列

【C语言蓝桥杯每日一题】—— 递增序列&#x1f60e;前言&#x1f64c;递增序列&#x1f64c;总结撒花&#x1f49e;&#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#xff1a;全神贯注的上吧&#xff01;&#xff01;&#xff01; &#x1f60a;作者…...

node_express框架01

01_express 基本结构 注意点&#xff1a;app.get 指定了 get 方法&#xff0c;如果是 app.all 就是指定了所有的请求方法&#xff08;例如&#xff1a;post delete 都是包含的&#xff09;&#xff0c;而 app.get(/) 里面访问的是根路径&#xff0c;如果访问别的路径&#xff…...

想转行做程序员,该怎么选择开发语言?哪个岗位工资最高?

本文主要针对零基础想了解或者转行从事开发岗的同学。 我们收集了往届毕业同学和一些正在咨询的同学&#xff0c;发现大家在学习初期&#xff0c;对转行互联网做开发&#xff0c;最多的疑问或者顾虑大体分为几类&#xff1a; 现在哪门语言比较火&#xff1f; 学什么语言好找到工…...

JavaWeb——【笔记】3.2JavaWeb_Web核心_Request(请求)+Response(响应)

Request(请求)Response(响应)两个对象 request、response是service()方法中的两个参数。作用分别是获取请求数据进行逻辑处理&#xff1b;对数据解析设置响应数据 一、简介 示例: 二、Request(请求) 1、Request继承体系 能更清楚其是由谁创建及查阅什么文档 2、Request获…...

HTML 标签和属性

一些标签 单双标签 双标签。双标签指标签是成对出现的&#xff0c;也就是有一个开始标签和一个结束标签&#xff0c;开始标签用 <标签名> 表示&#xff0c;结束标签用 </标签名> 表示&#xff0c;只有一对标签一起使用才能表示一个具体的含义。例如 <html>&…...

MySQL 连接的使用

MySQL 连接的使用 在前几章节中&#xff0c;我们已经学会了如何在一张表中读取数据&#xff0c;这是相对简单的&#xff0c;但是在真正的应用中经常需要从多个数据表中读取数据。 ​ 本章节我们将向大家介绍如何使用 MySQL 的 JOIN 在两个或多个表中查询数据。 你可以在 SEL…...

配置案例丨EtherCAT转Profinet网关连接凯福科技总线步进驱动器

西门子S7-1200/1500系列的PLC&#xff0c;采用PROFINET实时以太网通讯协议&#xff0c;需要连接带EtherCAT的通讯功能的伺服驱动器等设备&#xff0c;就必须进行通讯协议转换。小疆GW-PN-ECATM系列的网关提供了&#xff0c;快速可行的解决方案。GW-PN-ECATM支持两种实时以太网通…...

VSCODE连接ssh服务器时提示could not establish connection to解决方法

VSCODE连接ssh服务器时提示could not establish connection to解决方法 1.点击扩展设置 在Remote.ssh&#xff1a;config file中输入config路径 重新连接即可&#xff0c;如果是之前连接过ubuntu现在无法连接则需要打开刚刚的地址文件中删掉known_hostsj即可 虚拟机中ubuntu安…...

网络安全之防火墙 双机热备实验

目录 网络安全之防火墙 双机热备实验 实验图 基本配置 PC1 SW2 PC2 ​编辑 SW3配置 登陆防火墙图形界面 ​编辑 FW1的配置 FW2的配置 新建trust to untrust 区域的安全策略 配置心跳线 在FW1与FW2之间拉一条心跳线 ​编辑 配置FW1 g 1/0/2 口 ip ​编辑 配置FW2 g…...

Java高频面试题(2023最新整理)

Java的特点 Java是一门面向对象的编程语言。面向对象和面向过程的区别参考下一个问题。 Java具有平台独立性和移植性。 Java有一句口号&#xff1a;Write once, run anywhere&#xff0c;一次编写、到处运行。这也是Java的魅力所在。而实现这种特性的正是Java虚拟机JVM。已编…...

mongoDB学习笔记

1.大数据定义&#xff1a; 数据量级大 byte kb MB GB TB PB ... 数据种类多 数据维度 例如&#xff1a;人物画像 数据处理速度快 数据有价值 问题&#xff1a;①.存储 &#xff1f; ②.数据分析&#xff1f; ③.高并发&#xff1f; 大数据应用领域: 电商&#xff08;推…...

快速融人,融资的共享模式,实体,线上皆可参考

有一种模式现在非常流行&#xff0c;它既能帮助商家快速收钱&#xff0c;又能帮助商家快速裂变更多客户&#xff0c;这个神奇的模式就是共享股东模式&#xff0c;现在很多老板都在用这个模式。 梦龙商业案例分析&#xff0c;带你了解商业背后的秘密 这个模式也适用于很多个行…...

纯干货版阿里巴巴国际站入门攻略

阿里巴巴国际站作为目前全球排名名列前茅的B2B电商平台&#xff0c;很多跨境电商卖家都很想入局。但是目前很多公司的国际站都没有专职运营的人员&#xff0c;只是靠外贸业务员操作&#xff0c;所以涉猎的都是比较浅的东西。今天龙哥就来讲讲如果想要深研这个平台的话&#xff…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

智能分布式爬虫的数据处理流水线优化:基于深度强化学习的数据质量控制

在数字化浪潮席卷全球的今天&#xff0c;数据已成为企业和研究机构的核心资产。智能分布式爬虫作为高效的数据采集工具&#xff0c;在大规模数据获取中发挥着关键作用。然而&#xff0c;传统的数据处理流水线在面对复杂多变的网络环境和海量异构数据时&#xff0c;常出现数据质…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

PostgreSQL——环境搭建

一、Linux # 安装 PostgreSQL 15 仓库 sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-$(rpm -E %{rhel})-x86_64/pgdg-redhat-repo-latest.noarch.rpm# 安装之前先确认是否已经存在PostgreSQL rpm -qa | grep postgres# 如果存在&#xff0…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...