1. 환경
제3자 호출을 제공하기 위해 SpringBoot 기반 인터페이스를 작성합니다. Alibaba의 음성 인식 기능을 사용하는 방법과 유사하게 HTTP 요청을 보내 음성 인식을 수행하는 Alibaba의 패키지 API를 호출할 수 있습니다. 이 기사에서는 주로 SpringBoot에서 인터페이스를 개발하고 다른 사람들이 이를 안전하게 호출할 수 있도록 하는 방법을 기록합니다.
사용된 종속성:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>top.lukeewin</groupId>
<artifactId>Signature</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Signature</name>
<description>Signature</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. 암호화 알고리즘 선택
MD5 알고리즘을 사용한 암호화는 그다지 안전하지 않으므로 여기서는 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;
@Override
public 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 {
@Resource
private SignatureInterceptor signatureInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(signatureInterceptor).addPathPatterns("/**").excludePathPatterns("/ban");
}
}
주의점:
@Configuration
주석이 필요합니다.- 새로운 사용자 정의 인터셉터 클래스를 사용하여 추가할 수 없으며 주입을 사용하여 주입해야 합니다. 즉, 이렇게 쓸 수는 없습니다.
registry.addInterceptor(new SignatureInterceptor()).addPathPatterns("/**")
6. 인터페이스 응답 형식 통일
두 개의 도구 클래스를 만듭니다. 하나는 응답 기본 클래스이고 다른 하나는 오류 클래스입니다.
응답 기본 클래스:BaseResponse
@Data
public class BaseResponse<T> 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> BaseResponse<T> success(T data) {
BaseResponse<T> 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에 업로드되었습니다. 텍스트 내용을 읽고 싶지 않다면 비디오를 시청할 수도 있습니다.