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

封装自己的api签名sdk

api平台接口调用,需要通过签名去核对是不是有效的用户,,一般会给两个key,acceeKeysecretKey,第一个相当于用户名,第二个相当于密钥,,,前端通过一定的算法,,将内容和密钥 生成一个签名,,,
后端再根据 内容和密码,生成一个签名,,, 比对这两个签名是否一致,如果一致就是正常用户

这样也不安全,,别人可能会重发你的请求,,盗用你的签名一直刷你的请求,,,
设置一个nonce:唯一字符串,,请求一次记录一次,保证不重复,,但是只设置一个nonce服务器压力会很大,,设置一个timestamp 来筛选掉前后五分钟的请求,


package com.cj.apiclient;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.cj.apiclient.model.User;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author cc
 * @date 2025-04-04 21:05
 **/

public class ApiClient {


    private String baseUrl = "http://localhost:8080";
    private String accessKey;
    private String secretKey;

    public ApiClient(String accessKey, String secretKey) {
        this.accessKey = accessKey;
        this.secretKey = secretKey;
    }



    public String getUsernameByGet(User user){
        String json = JSONUtil.toJsonStr(user);

        HttpResponse httpResponse = HttpRequest.get(baseUrl + "/user/get")
                .addHeaders(getHeaderMap(json))
                .execute();

        String body = httpResponse.body();
        return body;

    }



    private Map<String, String> getHeaderMap(String body) {
        Map<String, String> map = new HashMap<>();
        map.put("accessKey", accessKey);
        map.put("nonce", UUID.randomUUID().toString());
        map.put("timestamp", System.currentTimeMillis() + "");
        map.put("body",body);
        map.put("sign",StringUtils.genSign(body,secretKey));
        return map;
    }
}


public class StringUtils {

    public static String genSign(String body,String secretKey){
        Digester md5 = new Digester(DigestAlgorithm.MD5);
        String content = body+"."+secretKey;
        return md5.digestHex(content);
    }
}
  @GetMapping("/user/get")
    public String getUsernameByGet(User user, HttpServletRequest request){

        String accessKey = request.getHeader("accessKey");
        String body = request.getHeader("body");

        // 判断时间戳是否在前后五分钟之内
        String timestamp = request.getHeader("timestamp");
        // 判断随机数是否使用过,,可以使用redis的ttl
        String nonce = request.getHeader("nonce");

        String sign = request.getHeader("sign");

        String s = StringUtils.genSign(body, "123");
        if (!s.equals(sign)){
            throw new RuntimeException("签名错误");
        }

        return "hehe";

    }
springboot自定义starter

自动配置的包,加了之后写配置文件,有自动提示

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

自定义starter,相当于配置了一个带默认属性的bean,,在META-INF文件夹下面添加spring.factories文件,将配置类写进去:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.cj.apiclient.ApiClientConfig

遇到的问题,默认属性写在appilication.properites不生效,,写在application.yml中生效

http://www.dtcms.com/a/111508.html

相关文章:

  • 数据结构 -- 图的存储
  • SpringBoot定时任务深度优化指南
  • ubuntu部署ollama+deepseek+open-webui
  • OpenCV 实现对形似宝马标的黄黑四象限标定位
  • 字符串移位包含问题
  • CExercise_1_4continue关键字在while循环和for循环中,实现的功能有什么区别?
  • Neo4j操作数据库(Cypher语法)
  • NO.61十六届蓝桥杯备战|基础算法-双指针|唯一的雪花|逛画展|字符串|丢手绢(C++)
  • 管理系统 UI 设计:提升企业办公效率的关键
  • (多看) CExercise_05_1函数_1.2计算base的exponent次幂
  • 花卉识别分类系统,Python/resnet18/pytorch
  • MySQL简介
  • 大钲资本押注儒拉玛特全球业务,累计交付超2500条自动化生产线儒拉玛特有望重整雄风,我以为它破产倒闭了,担心很多非标兄弟们失业
  • SpringBoot配置文件多环境开发
  • 空中无人机等动态目标识别2025.4.4
  • Nacos注册中心AP模式核心源码分析(单机模式)
  • 前端知识点---本地存储(javascript)
  • IObit Uninstaller:深度清理残留文件
  • 黑马点评_知识点
  • #Liunx内存管理# 在32bit Linux内核中,用户空间和内核空间的比例通常是3:1,可以修改成2:2吗?
  • Flutter 手搓日期选择
  • 浅析联咏NT9856X各种LCD显示屏接口技术
  • 操作系统(三):FreeRTOS实时性机制分析
  • 音视频(四)android编译
  • 【2019】【论文笔记】高resolution无透镜的THz成像和测距——
  • antvX6节点全选后鼠标通过拖拉调整视图的展示位置
  • 基于springboot微信小程序的旅游攻略系统(源码+lw+部署文档+讲解),源码可白嫖!
  • 码曰编程大模型-学编程的好工具
  • 【嵌入式学习4】模块、包、内置模块、异常
  • CherryStudio MCP实战(一)filesystem篇