山西做网站的公司哪个好,环球军事最新新闻,广东蕉岭县建设局网站,企业网站维护建设ppt1. 环境
基于SpringBoot编写一个接口#xff0c;提供给第三方调用。类似于我们使用阿里的语音识别功能#xff0c;我们可以调用阿里封装好的api#xff0c;也就是通过发送HTTP请求的方式来做语音识别。本篇文章主要记录在SpringBoot中我们是如何开发接口并让别人可以安全调…1. 环境
基于SpringBoot编写一个接口提供给第三方调用。类似于我们使用阿里的语音识别功能我们可以调用阿里封装好的api也就是通过发送HTTP请求的方式来做语音识别。本篇文章主要记录在SpringBoot中我们是如何开发接口并让别人可以安全调用的。
使用到的依赖pom.xml
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion3.2.1/versionrelativePath/ !-- lookup parent from repository --/parentgroupIdtop.lukeewin/groupIdartifactIdSignature/artifactIdversion0.0.1-SNAPSHOT/versionnameSignature/namedescriptionSignature/descriptionpropertiesjava.version17/java.version/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactId/dependency/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdconfigurationexcludesexcludegroupIdorg.projectlombok/groupIdartifactIdlombok/artifactId/exclude/excludes/configuration/plugin/plugins/build
/project2. 加密算法的选择
使用MD5这种算法加密是不太安全的所以这里我们使用hash算法中的HmacSHA256加密算法来生成签名当我们请求接口时我们使用把签名和时间戳带上为啥还要带上时间戳呢是因为我们之后要控制签名的过期时间需要根据这个前端传递过来的时间戳来计算过期时间。
下面是加密工具类
public class SignatureUtil {public static String getSignature(String timestamp, String apiKey, String apiSecret) {// 构建签名字符串String signatureString apiKey timestamp;String signature null;// 计算签名try {Mac sha256Hmac Mac.getInstance(HmacSHA256);SecretKeySpec secretKey new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), HmacSHA256);sha256Hmac.init(secretKey);byte[] signatureBytes sha256Hmac.doFinal(signatureString.getBytes(StandardCharsets.UTF_8));signature Base64.getEncoder().encodeToString(signatureBytes);} catch (NoSuchAlgorithmException | InvalidKeyException e) {throw new RuntimeException(e);}return signature;}
}3. 编写一个接口
这里简单编写一个音频转码的接口来模拟我们开发接口的整个过程。
RestController
public class TransferController {RequestMapping(/transfer)public BaseResponse transfer() {return BaseResponse.success(转码成功);}RequestMapping(/ban)public BaseResponse ban() {return BaseResponse.error(ErrorCode.VERIFY_NO_PASS);}
}4. 自定义一个拦截器
自定义拦截器对全面请求进行拦截判断是否传递了签名和时间戳并且判断传递过来的签名和后端计算出来的签名一不一致还需判断传递到后端时这个签名有没有过期如果上面这些条件有一个不成立就进行拦截否则放行。
Component
public class SignatureInterceptor implements HandlerInterceptor {Value(${apiKey})private String apiKey;Value(${apiSecret})private String apiSecret;Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String sign request.getParameter(sign);String timestamp request.getParameter(timestamp);if (StringUtils.isNotBlank(sign) StringUtils.isNotBlank(timestamp)) {String signature SignatureUtil.getSignature(timestamp, apiKey, apiSecret);if (StringUtils.isNotBlank(signature) signature.equals(sign) System.currentTimeMillis() - Long.parseLong(timestamp) 50 * 1000) {return true;} else {request.getRequestDispatcher(/ban).forward(request, response);return false;}} else {request.getRequestDispatcher(/ban).forward(request, response);return false;}}
}注意点
必须要把该类交给Spring IOC容器进行管理也就是需要在类上面添加一个注解Component拦截后需要给调用方一个提示否则调用方不知道是否被拦截所以这里需要使用request.getRequestDispatcher(/ban).forward(request, response);必须要放行拦截的URL如果不放行会产生死循环在这里也就是需要放行/ban接口
5. 编写一个拦截器的配置类
编写拦截器配置类把自定义的拦截器添加到配置类中。
Configuration
public class InterceptorConfig implements WebMvcConfigurer {Resourceprivate SignatureInterceptor signatureInterceptor;Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(signatureInterceptor).addPathPatterns(/**).excludePathPatterns(/ban);}
}注意点
必须要有Configuration注解不能使用new 自定义拦截器类的方式添加进来必须要使用注入的方式注入进来。也就是不能写成这样registry.addInterceptor(new SignatureInterceptor()).addPathPatterns(/**)
6. 统一接口的响应格式
创建两个工具类一个是响应基类一个是错误类。
响应基类BaseResponse
Data
public class BaseResponseT implements Serializable {private static final long serialVersionUID 4L;private Integer code;private String message;private Long timestamp System.currentTimeMillis();private T data;public static T BaseResponseT success(T data) {BaseResponseT resultData new BaseResponse();resultData.setCode(200);resultData.setMessage(OK);resultData.setData(data);return resultData;}public static BaseResponse error(ErrorCode errorCode) {BaseResponse resultData new BaseResponse();resultData.setCode(errorCode.getCode());resultData.setMessage(errorCode.getMessage());return resultData;}
}这里用到了Data注解是lombok提供的一个注解所以你需要在pom.xml中引入lombok依赖。
编写错误码类ErrorCode
public enum ErrorCode {VERIFY_NO_PASS(300, 签名验证未通过);private final Integer code;private final String message;ErrorCode(Integer code, String message) {this.code code;this.message message;}public Integer getCode() {return code;}public String getMessage() {return message;}
}7. 配置文件
在自定义拦截器中我们通过Value注解从项目的配置文件application.yml中获取apiKey和apiSecret。
application.yml文件如下
apiKey: dhkadj123fda
apiSecret: hgjdakf12314sdf对应的视频教程已经上传到B站中如果不喜欢看文字内容也可以看视频