소스 검색

fix:模拟开放API模块,添加API的认证和鉴权机制

yang yi 11 달 전
부모
커밋
750f829360

+ 2 - 0
.gitignore

@@ -30,4 +30,6 @@
 !/sql
 !/ui/yangyi-open-api-platform-ui
 !/open-api
+!/open-api-commom
+!/open-api-client
 !.gitignore

+ 10 - 0
open-api/pom.xml

@@ -46,6 +46,16 @@
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
+        <dependency>
+            <groupId>space.anyi</groupId>
+            <artifactId>open-api-commom</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.11</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 18 - 1
open-api/readme.md

@@ -1 +1,18 @@
-模拟开放API的项目
+# 模拟开放API的项目
+提供三个模拟的获取用户名的开放API
+## API的认证和鉴权
+常用的参数
+- accessKey: 相当于账号
+- secretKey: 相当于密码
+- timestamp: 时间戳
+- sign: 签名
+- nonce: 随机数
+
+客户端传输四个参数即可:
+- accessKey
+- timestamp
+- sign
+- nonce
+客户端传输参数时一般不能直接传输secretKey,所以需要使用签名算法对参数进行加密,服务器端收到请求后,再使用相同的签名算法对参数进行解密,解密成功则说明请求是合法的,否则说明请求不合法。
+sign = md5(secretKey + timestamp + accessKey),防止secretKey直接网络传输被中间人攻击
+nonce = 随机数,防止重放攻击

+ 48 - 2
open-api/src/main/java/space/anyi/openapi/controller/UserController.java

@@ -1,7 +1,12 @@
 package space.anyi.openapi.controller;
 
+import cn.hutool.crypto.digest.MD5;
 import org.springframework.web.bind.annotation.*;
-import space.anyi.openapi.model.User;
+import space.anyi.openApi.comom.model.User;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.nio.charset.StandardCharsets;
 
 /**
  * @ProjectName: yangyi-open-api-platform
@@ -44,9 +49,50 @@ public class UserController {
     }
     //通过RequestBody的方式
     @PostMapping("/body")
-    public String getUserNameByBody(@RequestBody User user){
+    public String getUserNameByBody(@RequestBody User user, HttpServletRequest servletRequest, HttpServletResponse servletResponse){
+        System.out.println(user);
+        servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.name());
+        servletResponse.setContentType("text/html;charset=utf-8");
+        //获取认证鉴权参数
+        /**
+         * 客户端传输四个参数即可:
+         * - accessKey
+         * - timestamp
+         * - sign
+         * - nonce
+         */
+        String accessKey = servletRequest.getHeader("accessKey");
+        String timestamp = servletRequest.getHeader("timestamp");
+        String sign = servletRequest.getHeader("sign");
+        String nonce = servletRequest.getHeader("nonce");
+        //校验
+        String[] data =  selectFormDB();
+        String ACCESS_KEY = data[0];
+        String SECRET_KEY = data[1];
+        //校验accessKey
+        if (!ACCESS_KEY.equals(accessKey)) {
+            return "accessKey错误";
+        }
+        //todo:校验timestamp,时间误差不超过1minute
+        //校验sign
+        if (!MD5.create().digestHex16(SECRET_KEY+timestamp+SECRET_KEY).equals(sign)) {
+            return "secretKey错误";
+        }
+        //todo:校验nonce防止重放攻击
         String username = user.getName();
         System.out.println(username);
         return username;
     }
+
+    /**
+     * 模拟从数据库查询accessKey和secretKey
+     * @return {@code String[] }
+     * @description:
+     * @author: 杨逸
+     * @data:2025/10/18 14:49:58
+     * @since 1.0.0
+     */
+    private String[] selectFormDB() {
+        return new String[]{"accessKey","secretKey"};
+    }
 }

+ 0 - 15
open-api/src/main/java/space/anyi/openapi/model/User.java

@@ -1,15 +0,0 @@
-package space.anyi.openapi.model;
-
-import lombok.Data;
-
-/**
- * @ProjectName: yangyi-open-api-platform
- * @FileName: User
- * @Author: 杨逸
- * @Data:2025/10/18 13:19
- * @Description:
- */
-@Data
-public class User {
-    private String name;
-}