奇趣5分彩

Java完奇趣5分彩API sign署名校验的方式详解

 更新时候:2022年07月12日 11:00:38   作者:TopDuang  
为了避免奇趣5分彩心人进犯,偶然咱们须要停止API sign 署名校验。本文将用Java说话完奇趣5分彩API sign 署名校验,感乐趣的小火伴能够测验考试一下

1. 媒介

目标:为避免奇趣5分彩心人进犯。

场景:

  • 名目外部前后端挪用,这类场景只须要做通俗参数的署名校验和过时要求校验,目标是为了避免进犯者挟制要求 url 后不法要求接口。
  • 开放平台向第三方利用供给才能,这类场景除通俗参数校验和要求过时校验外,还要斟酌 3d 利用的受权机制,不被受权的利用就算传入了正当的参数也不能被许可要求胜利。

2. 署名天生战略

接上去胪陈场景 2,实在场景 1 也包罗在场景 2 外部。

1.举例要求 url:

http://api.abc.com/a-service/orders?orderType=1001&requestFrom=IOS&pageNum=2&pageSize=10

要求参数为:

参数名地位备注举例
X-Access-Keyheader客户端受权码,办事端供给,和 accessSecret 配对(场景 1 无此参数)app1
X-Access-Tokenheader今后登录用户 tokend7b5808c3f443eb5a496225468c7e4a5
X-UTCTimeheader今后发送要求时的时候2022-02-16T09:12:43.083Z
X-Randomheader要求随机数341be97d9aff90c9978347f66f945b77
orderTypequery定单范例1001
requestFromquery定单来历IOS
pageNumquery分页参数10
pageSizequery分页参数2

2.设原始参数为 stringA,stringA 奇趣5分彩增加 X-Access-Key、X-UTCTime、X-Random 牢固参数,将 stringA 内非奇趣5分彩参数值和 header 的参数根据参数名 ASCII 码从小到大排序(字典序),利用 URL 键值对的格局(即 key1=value1&key2=value2…)拼接奇趣5分彩字符串 stringB。

注重以下法则:

  • 参数名 ASCII 码从小到大排序(字典序);
  • 若是参数的值为奇趣5分彩不到场署名;
  • 参数名辨别巨细写;
  • 考证挪用前往或自动告诉署名时,传递的 sign 参数不到场署名,将天生的署名与该 sign 值作校验。
// 终究拼接为stringB:
orderType=1001X-UTCTime=2022-02-16T09:12:43.083ZpageSize=10X-Access-Key=app1X-Access-Token=d7b5808c3f443eb5a496225468c7e4a5pageNum=2requestFrom=IOSX-Random=341be97d9aff90c9978347f66f945b77

3.在 stringB 最初拼接上 accessSecret (密钥) 获得 stringC 字符串,并对 stringC 停止 MD5 运算,获得 sign 值。

// 最初拼上accessSecret获得stringC:
orderType=1001X-UTCTime=2022-02-16T09:12:43.083ZpageSize=10X-Access-Key=app1X-Access-Token=d7b5808c3f443eb5a496225468c7e4a5pageNum=2requestFrom=IOSX-Random=341be97d9aff90c9978347f66f945b77&accessSecret=192006250b4c09247ec02edce69f6a2d
// md5加密获得终究署名奇趣5分彩果sign:
sign=e1a4907ef03adee3fa8d395552814f4e

4.将原始的要求 url 拼接上 sign 构奇趣5分彩终究的要求 url。

http://api.abc.com/a-service/orders?orderType=1001&requestFrom=IOS&pageNum=2&pageSize=10&sign=0f5a3cc534961d129a25d52d7ed8d003

5.终究要求 url 以下:

http://api.abc.com/a-service/orders?orderType=1001&requestFrom=IOS&pageNum=2&pageSize=10&sign=0f5a3cc534961d129a25d52d7ed8d003

参数名地位备注举例
X-Access-Keyheader客户端受权码,办事端供给,和 accessSecret 配对(场景 1 无此参数)app1
X-Access-Tokenheader今后登录用户 tokend7b5808c3f443eb5a496225468c7e4a5
X-UTCTimeheader今后发送要求时的时候2022-02-16T09:12:43.083Z
X-Randomheader要求随机数341be97d9aff90c9978347f66f945b77
orderTypequery定单范例1001
requestFromquery定单来历IOS
pageNumquery分页参数10
pageSizequery分页参数2

6.办事端 gateway 一样做 sign 署名加密和校验,若是校验不经由进程则申明要求不法,间接谢绝,经由进程则下发到营业办事停止一般要求处置。

3. API 署名算法 Java 完奇趣5分彩

public class SignUtil {

    /**
     * 天生署名
     *
     * @param accessSecret accessSecret
     * @param url          url
     * @param headers      headers
     * @param body         post的body体
     * @param <T>          body体泛型
     * @return sign
     */
    public static <T> String sign(String accessSecret, String url, Map<String, Object> headers, T body) throws IllegalAccessException {
        Map<String, Object> signMap = new HashMap<>();
        if (headers != null) {
            signMap.putAll(headers);
        }
        Map<String, Object> paramMap = getUrlParams(url);
        if (paramMap != null) {
            signMap.putAll(paramMap);
        }
        Map<String, Object> bodyMap = getBodyParams(body);
        if (bodyMap != null) {
            signMap.putAll(bodyMap);
        }

        StringBuffer sb = new StringBuffer();
        signMap.forEach((k, v) -> {
            sb.append(k).append("=").append(v).append("&");
        });
        sb.append("accessSecret=").append(accessSecret);
        return stringToMD5(sb.toString());
    }

    private static Map<String, Object> getUrlParams(String url) {
        if (StringUtils.isBlank(url) || !url.contains("?")) {
            return null;
        }
        Map<String, Object> paramMap = new HashMap<>();
        String params = url.split("\\?")[1];
        for (String param : params.split("&")) {
            String[] p = param.split("=");
            paramMap.put(p[0], p[1]);
        }
        return paramMap;
    }

    private static <T> Map<String, Object> getBodyParams(T body) throws IllegalAccessException {
        if (body == null) {
            return null;
        }
        Map<String, Object> bodyMap = new HashMap<>();
        for (Field field : body.getClass().getDeclaredFields()) {
            field.setAccessible(true);
            bodyMap.put(field.getName(), field.get(body));
        }
        return bodyMap;
    }

    private static String stringToMD5(String plainText) {
        byte[] secretBytes = null;
        try {
            secretBytes = MessageDigest.getInstance("md5").digest(
                    plainText.getBytes());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("不这个md5算法!");
        }

        return new BigInteger(1, secretBytes).toString(16);
    }
}

4. 测试一下

public class App {
    public static void main(String[] args) throws IllegalAccessException {
        String url = "http://api.abc.com/a-service/orders?orderType=1001&requestFrom=IOS&pageNum=2&pageSize=10";
        Map<String, Object> headerMap = new HashMap<>();
        headerMap.put("X-Access-Key", "app1");
        headerMap.put("X-Access-Token", "d7b5808c3f443eb5a496225468c7e4a5");
        headerMap.put("X-UTCTime", generateDate());
        headerMap.put("X-Random", "341be97d9aff90c9978347f66f945b77");
        BodyVO body = new BodyVO(100000001L, "yangcan", new Date());

        String sign = SignUtil.sign("sdfsdfdsfdsfds", url, headerMap, body);
        System.out.println(sign);
    }

    /**
     * 获得今后时候的UTC格局
     */
    private static String generateDate() {
        Date now = new Date();
        DateFormat format = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy", Locale.US);
        return format.format(now);
    }

    @Data
    @AllArgsConstructor
    public static class BodyVO {
        private Long ycId;
        private String ycName;
        private Date ycTime;
    }
}

输入:

sign = 4f52eb34b30129a8d511dc803044086b

到此这篇对于Java完奇趣5分彩API sign署名校验的方式详解的文章就先容到这了,更多相干Java API署名校验内容请搜刮剧本之奇趣5分彩之前的文章或持续阅读上面的相干文章但愿大师今后多多撑持剧本之奇趣5分彩!

相干文章

最新批评