编写开放接口与思考

2024-08-21 07:44
文章标签 接口 思考 编写 开放

本文主要是介绍编写开放接口与思考,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

编写开放接口与思考

一、情景描述:

当一个项目开发一定程度时,会有跟合作厂商对接共同开发的情况,那么如果合作厂商想要使用你项目中的某个接口,你该如何把接口暴露给他们?

二、实现方式分析

1、因为现在接口大部分都需要携带token才能访问的,直接让这个接口免token访问是一种方式,也是最简单的方式,但是风险性太高,免token就相当于所有人都能够调用这个接口,不安全不推荐;

2、如果我们想要提供接口供别人调用,首先我们可以模仿市面上已有的提供对外接口的方式,站在巨人的肩膀上,让你更快一步

像市面上大部分的开放平台,都会提供很多开放的接口

  • 微信公众号
    在这里插入图片描述
  • 海康威视开放平台
    在这里插入图片描述
  • 京东支付开放平台在这里插入图片描述
    可以发现,这些开放平台都有一个共同的特点
    提供的接口参数都需要像公钥,签名这样的加密参数进行校验,这些参数一般都是开放平台提供

也就不难猜出,如果要提供一个开放接口,在业务逻辑之上,要添加身份认证校验的功能
在这里插入图片描述

三、实现设计

结合已有的提供接口的方式,下面我来编写一个开放接口demo供大家参考

设计思路:

1、提供给调用者参数:appid,appkey
appid:身份id
appkey:公钥
解释:appid作为识别用户的标识,appkey公钥用来进行加密算法运算生成验证签名

2、加密规则:使用appid和appkey公钥+实时时间戳生成sign签名
3、使用方式:调用者使用appid和appkey公钥通过加密算法生成sign签名,然后把appid,sign,timestamp作为请求头来调用接口
timestamp:时间戳,如果超过范围则不允许调用接口
注意
1、既然要验证身份,那么创建身份也是需要由接口提供方来实现的;
2、创建好的身份信息建议入库保存;
3、为了保证时效性,添加timestamp参数;
只有三个参数都验证通过了,才能走接口业务代码

实现思路

1、验证appid

查询参数appid在数据库中是否存在,如果不存在则验证失败,如果存在则进入下一步

2、验证sign

查询参数sign是否满足自己要求的加密算法方式,如果不满足则sign比对不一致,如果满足则验签成功进入下一步

3、验证timestamp

查询timestamp是否在当前十分钟有效期内(时间要求可自定义),如果不满足则超时退出,满足则可进入业务层

四、代码实现

demo结构如下
在这里插入图片描述
controller层

@Slf4j
@RequestMapping("hello")
@RestController
public class HelloController {private static final long  diffMile = 900000;//15*60*1000毫秒=15分钟内有效@Value("${appsecret}")private String  appsecret;@Value("${appid}")private String  appid;@RequestMapping("/oneInterface")public Result oneInterface(HttpServletRequest request) {Result ret = new Result();String timestamp = request.getHeader("timestamp");String checkappid = request.getHeader("appid");String sign = request.getHeader("sign");if (checkappid == null || timestamp == null || sign == null) {log.info("请求参数缺少");return ret.fail("请求参数缺少");}if (!appid.equals(checkappid)) {//校验appidlog.info("请求appid不正确");return ret.fail("请求appid不正确");}long nowTime = System.currentTimeMillis();long reqTime;try {reqTime = Long.parseLong(timestamp);} catch (Exception e) {log.info("时间戳转换异常", e);return ret.fail("时间戳转换异常");}if (Math.abs(nowTime - reqTime) > diffMile ) {//差值绝对值大于区间log.info("与服务器时间相差超过15分钟");return ret.fail("与服务器时间相差超过15分钟");}//校验签名String checksign = MD5Util.MD5Encode(appid.concat(appsecret).concat(timestamp), "UTF-8");if (!sign.equals(checksign)) {log.info("签名不正确");return ret.fail("签名不正确");}log.info("校验成功");//业务逻辑return ret.ok("接口调用成功");}
}

加密工具类

package com.windwoo.utils;import java.security.MessageDigest;public class MD5Util {private static String byteArrayToHexString(byte b[]) {StringBuffer resultSb = new StringBuffer();for (int i = 0; i < b.length; i++)resultSb.append(byteToHexString(b[i]));return resultSb.toString();}private static String byteToHexString(byte b) {int n = b;if (n < 0)n += 256;int d1 = n / 16;int d2 = n % 16;return hexDigits[d1] + hexDigits[d2];}public static String MD5Encode(String origin, String charsetname) {String resultString = null;try {resultString = new String(origin);MessageDigest md = MessageDigest.getInstance("MD5");if (charsetname == null || "".equals(charsetname))resultString = byteArrayToHexString(md.digest(resultString.getBytes()));elseresultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));} catch (Exception exception) {}return resultString;}private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
}

上述代码使用的加密方式是对称加密,也就是提供者和使用者密钥appsecret是一样的

接口调试
在这里插入图片描述

在编写好接口后,还需要告诉调用者生成签名的方式,demo中实现方式是将appid,appsecret,timestamp字符串进行拼接然后md5加密

String sign = MD5Util.MD5Encode(appid.concat(appsecret).concat(timestamp), "UTF-8");

五、总结:

以上便是自定义开放接口全部步骤,当然校验的方式也有很多种,加密方式也有很多种,像对称加密,非对称加密,信息摘要,数字签名等,不同的加密算法对应着不同的应用场景,大家可以选择适合的方式来调整

这篇关于编写开放接口与思考的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1092548

相关文章

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

MyBatis-Flex BaseMapper的接口基本用法小结

《MyBatis-FlexBaseMapper的接口基本用法小结》本文主要介绍了MyBatis-FlexBaseMapper的接口基本用法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具... 目录MyBATis-Flex简单介绍特性基础方法INSERT① insert② insertSelec

Spring排序机制之接口与注解的使用方法

《Spring排序机制之接口与注解的使用方法》本文介绍了Spring中多种排序机制,包括Ordered接口、PriorityOrdered接口、@Order注解和@Priority注解,提供了详细示例... 目录一、Spring 排序的需求场景二、Spring 中的排序机制1、Ordered 接口2、Pri

Idea实现接口的方法上无法添加@Override注解的解决方案

《Idea实现接口的方法上无法添加@Override注解的解决方案》文章介绍了在IDEA中实现接口方法时无法添加@Override注解的问题及其解决方法,主要步骤包括更改项目结构中的Languagel... 目录Idea实现接China编程口的方法上无法添加@javascriptOverride注解错误原因解决方

Java function函数式接口的使用方法与实例

《Javafunction函数式接口的使用方法与实例》:本文主要介绍Javafunction函数式接口的使用方法与实例,函数式接口如一支未完成的诗篇,用Lambda表达式作韵脚,将代码的机械美感... 目录引言-当代码遇见诗性一、函数式接口的生物学解构1.1 函数式接口的基因密码1.2 六大核心接口的形态学

关于rpc长连接与短连接的思考记录

《关于rpc长连接与短连接的思考记录》文章总结了RPC项目中长连接和短连接的处理方式,包括RPC和HTTP的长连接与短连接的区别、TCP的保活机制、客户端与服务器的连接模式及其利弊分析,文章强调了在实... 目录rpc项目中的长连接与短连接的思考什么是rpc项目中的长连接和短连接与tcp和http的长连接短

详解Java如何向http/https接口发出请求

《详解Java如何向http/https接口发出请求》这篇文章主要为大家详细介绍了Java如何实现向http/https接口发出请求,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用Java发送web请求所用到的包都在java.net下,在具体使用时可以用如下代码,你可以把它封装成一

利用Python编写一个简单的聊天机器人

《利用Python编写一个简单的聊天机器人》这篇文章主要为大家详细介绍了如何利用Python编写一个简单的聊天机器人,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 使用 python 编写一个简单的聊天机器人可以从最基础的逻辑开始,然后逐步加入更复杂的功能。这里我们将先实现一个简单的

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

使用PyQt5编写一个简单的取色器

《使用PyQt5编写一个简单的取色器》:本文主要介绍PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16进制颜色编码,一款跟随鼠标刷新图像的RGB和16... 目录取色器1取色器2PyQt5搭建的一个取色器,一共写了两款应用,一款使用快捷键捕获鼠标附近图像的RGB和16