API接口安全设计

简介: API接口安全设计

image.png
1.Http接口安全概述:

   1.1、Http接口是互联网各系统之间对接的重要方式之一,使用http接口,开发和调用都很方便,也是被大量采用的方式,它可以让不同系统之间实现数据的交换和共享,但由于http接口开放在互联网上,那么我们就需要有一定的安全措施来保证不能是随随便便就可以调用;

   1.2、目前国内互联网公司主要采用两种做法实现接口的安全:

            一种是以支付宝等支付公司为代表的私钥公钥签名验证机制;

            一种是大量互联网企业都常采用的参数签名验证机制;
  1. Http接口安全演进:

         2.1.完全开放的接口(完全开放)
    
         2.2.接口参数签名(基本安全)
    
         2.3.接口参数签名+时效性验证(更加安全)
    
         2.4.接口参数私钥签名公钥验签(固若金汤)
    
         2.5.接口参数签名+Https(金钟罩)
    
         2.6.口参数私钥签名公钥验签+Https(金钟罩)
    
         总之:安全是相对的,只有相对的安全,没有绝对的安全!
    

3.Http接口安全设计及应用

     3.1 接口参数私钥签名公钥验签

先来看看私钥+公钥的安全模式,这是一种更为安全的方式,它通过私钥和公钥实现接口的安全,目前互联网中主要是以支付宝

为代表的公司采用这种机制;(有很多开放平台也是采用这种机制) . 具体业务流所示:

image.png

该签名是通过4个秘钥来实现的,分别是:

客户端应用私钥 , 客户端公钥 , 服务端应用私钥 , 服务端公钥.

私钥都是用来生成签名的,公钥都是用来解密的,客户端的公钥解密客户端的私钥生成的签名,服务端的公钥解密服务端的私钥生

成的签名,相信这样解释应该会比较好理解的.

    好了,下面就来看看是如何具体操作的,我的具体操作步骤:

    首先,4把密钥都是通过OpenSSL工具生成,你需要先获得这个工具:官方网站:https://www.openssl.org/

    介绍一下这个工具吧,OpenSSL 是一个开源的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序测试或其它目的使用;OpenSSL整个软件包大概可以分成三个主要的功能部分:SSL协议库、应用程序以及密码算法库;

    3.1.1确保Linux已经安装openssl  :  

           使用命令检查Linux是否已经安装openssl:yum list installed | grep openssl

           如果没有安装,则执行命令进行安装:yum install openssl openssl-devel -y

3.1.2创建秘钥生成的目的地(文件夹):

ps : 我是在根目录中的soft文件夹下创建的

mkdir server , mkdir client 先创建这两个文件,然后Linux会默认将生成的秘钥放入其中.

3.1.3 生成秘钥

进入server文件,输入openssl 进入Openssl命令行;
使用openssl生成私钥,执行如下命令:
genrsa -out rsa_private_key.pem 2048
注意一点Java开发者需要将私钥转换成PKCS8格式,其他语言不用这一步操作,执行如下命令:
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem
使用openssl生成公钥,执行如下命令:
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
退出openssl命令行:exit
经过以上步骤,我们可以在当前目录中(server)看到三个文件:
rsa_private_key.pem(RSA私钥)
rsa_private_key_pkcs8.pem(pkcs8格式RSA私钥)(我们java要使用的私钥是这一个)
rsa_public_key.pem(对应RSA公钥)

     client端的秘钥与server端的秘钥生成一样,这里就不叙述了,想体验的朋友自己按照上一步操作再做一遍即可.

3.2 Demo

  好了,现在就可以使用生成的秘钥来做一个简单的Demo来检验一下了.

  首先这里提供一个签名处理工具类:

  说明:该工具类依赖的包是java.security,该包JDK8才有,所以,如果使用下面这个Demo的话,建议检查自己的JDK是不是JDK8,如果是JDK8以下的版本,以下的Demo是用不了的.解决方法就是,使用第三方提供的依赖包,效果是相同的,依赖包如下:
<dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>RELEASE</version>
</dependency>

package com.kinglong.http.utils;
 
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
 
/**
 * 签名处理工具类
 * 
 * @author haojinlong
 *
 */
public class MyRSAUtils {
    
    public static final String CHARSET = "utf-8";
 
    /**
     * RSA私钥签名
     * 
     * @param src 客户端传过来的原始参数
     * @param priKey  我们的客户端私钥
     * @return  
     * @throws Exception
     */
    public static String sign (String src, String priKey) {
        try {
            KeyFactory fac = KeyFactory.getInstance("RSA");
            byte[] pribyte = Base64.getDecoder().decode(priKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
            RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec);
 
            Signature sigEng = Signature.getInstance("SHA1withRSA");
            sigEng.initSign(privateKey);
            sigEng.update(src.getBytes(MyRSAUtils.CHARSET));
 
            byte[] signature = sigEng.sign();
            return Base64.getEncoder().encodeToString(signature);
 
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * RSA公钥验证签名
     * 
     * @param src  客户端穿过来的原始数据
     * @param sign  签名
     * @param publicKey 我们的客户端公钥
     * @return
     */
    public static boolean signVerify (String sign, String src, String publicKey) {
        try {
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
 
            //将公钥变为一个字节数组
            byte[] encodedKey = Base64.getDecoder().decode(publicKey);
            //使用秘钥工厂生成一个公钥对象pubKey
            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
 
            //使用"SHA1WithRSA"算法,生成签名对象signature
            Signature signature = Signature.getInstance("SHA1WithRSA");
            signature.initVerify(pubKey);
            signature.update(src.getBytes(MyRSAUtils.CHARSET));
 
            boolean bverify = signature.verify(Base64.getDecoder().decode(sign));
            return bverify;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

package com.kinglong.http.HttpUtils;
 
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
*生成签名需要的辅助工具类
*/
public class SignUtils {
    /**
    *将传进来的无序参数,转换为有序的字符串输出
    */
    public static String generateSortSign(Map<String,Object>paramMap){
 
        Map<String,Object> treeMap = new TreeMap<String, Object>(paramMap);
        Set<Map.Entry<String,Object>> entrySet = treeMap.entrySet();
        Iterator<Map.Entry<String,Object>> iterator = entrySet.iterator();
        StringBuffer stringBuffer = new StringBuffer();
 
        while (iterator.hasNext()){
 
            Map.Entry<String,Object> entry=iterator.next();
            String keys = entry.getKey();
            String value = (String) entry.getValue();
            stringBuffer.append(keys).append(value);
 
        }
        return  stringBuffer.toString();
 
    }
 
}


package com.kinglong.http.controller;
 
import com.alibaba.fastjson.JSONObject;
import com.kinglong.http.HttpUtils.HttpClientUtils;
import com.kinglong.http.HttpUtils.SignUtils;
import com.kinglong.http.constans.Constans;
import com.kinglong.http.utils.MyRSAUtils;
 
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
public class HttpClient {
 
 
    public static void main(String[] args) {
 
        demo();
 
    }
 
    public static void demo(){
        String url ="http://localhost:8080/api/verifydemo";
 
    //这里仅做演示使用,所以随手写了几个信息
        String realName = "我是验证信息";
        String phone = "17000000000";
        String idCard = "6403021992120511111";
        String bankCard = "5555555555555555555555";
 
        //封装参数
        Map<String,Object> paramMap = new ConcurrentHashMap<String, Object>();
        paramMap.put("realName",realName);
        paramMap.put("phone",phone);
        paramMap.put("idCard",idCard);
        paramMap.put("bankCard",bankCard);
 
    //生成客户端签名,注意看,客户端这里生成签名的时候是使用的客户端私钥Constans.CLIENT_PRIVATE_KEY
        String sign = MyRSAUtils.sign(SignUtils.generateSortSign(paramMap),Constans.CLIENT_PRIVATE_KEY);
        paramMap.put("sign",sign);
 
    //发送请求时注意:因为肯定会不可避免的要输出中文字符,所以记得在使用HttpClient通信的时候,设置编码格式为utf-8
    //否则,我想你的签名验证成功的概率基本等于让两条平行线相交成功的概率
        String json = HttpClientUtils.doPostByEncode(url,paramMap,"utf-8");
 
        //解析json字符串
        JSONObject jsonObject = JSONObject.parseObject(json);
        String code = jsonObject.getString("code");
        String erroMessage = jsonObject.getString("erroMessage");
        JSONObject object = jsonObject.getJSONObject("object");
        String result = object.getString("result");
        String ret_sign = object.getString("ret_sign");//服务端发回的签名
        String resultDesc = object.getString("resultDesc");
 
        //封装参数准备进行验证该返回信息是否是由服务端发回的
    //验证时的参数可以根据自己公司的规范去选择,我这里就选了这两个参数,因为偷懒没有生成新的map,所以这里需要clear一下.
        paramMap.clear();
        paramMap.put("result",result);
        paramMap.put("resultDesc",resultDesc);
 
      //调用签名验证工具类进行签名验证
      //重点!!!敲黑板啦!!注意看,这里使用的是服务端的公钥来解密服务端发送的签名的,很多人肯定使用了客户端公钥来解密,必然是失败的
      //同理,在服务端要是用客户端的公钥解密客户端发送的签名,这个前面的流程图我觉得已经说得很明确了
  boolean isTrue = MyRSAUtils.signVerify(ret_sign,SignUtils.generateSortSign(paramMap),Constans.SERVER_PUBLIC_KEY);
 
        if (isTrue){
            System.out.println("返回正确信息,可以进行下一步操作");
        }else {
            System.out.println("返回错误信息,不可以进行下一步操作");
        }
 
    }
}

package com.kinglong.http.constans;
 
public class Constans {
        //客户端私钥
    public static final String CLIENT_PRIVATE_KEY="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQClEAp0NDHtb9w5iJfyNOh6DeCRv0RjGFA1CIQ6ZxpfIc65h03hUGsDjcZtWQQZf7d30hiVCcQLylJYJidHQbPcDWULRhObgUxFIFQ37UW8c8DHDiHPNVRjH47ePi9sZIYbVuaWOJkS9NAoSDTRDA1vS7ewWosA9WyUSEuWSEm6eQQV02nlhf/cIsu3biDmq8Y9ffg9lLgEYbH4VQu6bRXgqpy90OxFh3Jh16nbAZXqAJMKCZyJYo5B9ZN4No8Q/EMZe98DNFybOod7WTuQmrS5FM0vCsjQpczBwn+dny5grWl4YgUYgAWOnvPr2iMXVXLqbQjcVEMFKwr/71K9yVehAgMBAAECggEBAJi6nvGm2gu41SznFrEmA3XsIT66m6yVcqGfn7nqbJxZy84fRBCXOG2xYUkMdJ6jbj+QRu6geqXuLwMhSnbEdIfIXRZxYPMiUFAl+cdF5KDa+iU1DlOMJOkS6j75iyfgW7YwUmvtMrY3j+O17CkB3ex9QxoKrVPVwwHxYv9LI+1FT0Fd3157gIbkBTdXnKUc4O4Z4/FTcvPYNR2h9O79xQbcx0clUbj61yQxkxVyN25plxxAVoUW7mKNleH6nFAkeb/gYxLdwlUHm53cYowSDtbzo4udB6qPWj/PvCVgu7UatnEhcyX9ZKCBmrX3+EvWTw9A9dTDSMu4D9CX2QsUq4ECgYEA2pTWhw6ulzWlORu12WcUxDzCVuKV7dGXCQ2MRnGELLm7HzAmRIjd0LubGWAKwUNa6NhWVNsupI8/hDh3hyjGAiTVn0gowDVQj4s/vIx5aYMsg6nxzUl3KrjBJyORHnY8+fFp5V1SHr0G6jOTynsqX0ONMpNZ/zyxiOQG5vGs7A8CgYEAwVHJAe0Eqz2jwLHA10Afsh3vS2Otcjj1cj9jxz1ZFoYIbD64Mc77bem+9x7xpI4w6/WezUOO4gZ8RaAh7PpyMWbTwzq0QHS7bSzKMfpRALyVf7HyIS/QuTUA0oLZXx9vk4wAe0rZBNFuuEtyU3XgHz8OSY/uHeTXJWYtJHTIkU8CgYAD6YgRcMTVNgOYCxPtKTgo7wF3dqTCVe8DHXf2Rs/b0RM1UrJMpbp6ovD6ukpW/TKiWkTpTeb+0QWNA0m4ZJVusmQUbsEz94BSoWZppIYDynJAhQkr6HW2kQn7/ln5lpouyxBfJ5VxsWZvSK8Lf7rZa6caUaLZu6dd0N8CwS6cJwKBgD74B9RTwtiQXF1wyNKUNX7MF1zkG+P/v5s2IKcOSY13nRi9GTxIIke8ApL2BlnGYxMIz3Am2EyxNhtrvIE3VqjWyJVn8ryoCUDXfQjocygdRUjxyl+a9o7NP/ZR3sIIOEzEJogCakwSd9EZ6iRbWeRzopC9jB86ogWxkXS1gXsrAoGAEOvVsv8lpY+TCs3Q78pnedwFIXXkrOknrXq2gb+WHmSSDCELOaqWsX73rdbW4IcmJ6kT2d5bn6hH+/2Zw/+Xpy6maBeLxxscXBfLHwT/85YG5z21LuyikB7ht/tZCNxQOjEfvo5MdCwNN6GhpPSVwNjLAvtiImJYnlDuGPaG+RU=";
 
    //服务端公钥
    public static final String SERVER_PUBLIC_KEY="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqlG1v814kyQIEpLQnyxo/4RUku8PE+csGzH073XoW8xPdXAH8C7Y3isyDKSClTEGeS/SaqioYPFI+YlD0Eag1DEoVPkDcJeWsPv4FZr2ZO2wCenwqUrH5BM7ZapSBLenkgdhTF3SIUJMrTfJPaRJM1wb75SPawHO1zueM0cvcbeGNJOyCG69XPhour0Cei/HcflY3bXVx9kKH8vvAmbosAOrIwwdGSnV1YqSlApBmoobGYcaFPv5Clntghq+6P1ut2RSOrKinr0Q4wc4kIpnSY+j2oQ20OZ7rZXuLyGmMSsglvGwgTIoxHqkXpWP3qGFmYHSQgGCMFWxlT1t3e1AawIDAQAB";
}


说明:服务端的签名生成类,签名生成的辅助类都与客户端相同,所以,这里就不写了.

 

服务端的公共常量类:

package com.kinglong.http.constans;
 
public class Constans {
    //服务端私钥
    public static final String SERVER_PRIVATE_KEY="MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCqUbW/zXiTJAgSktCfLGj/hFSS7w8T5ywbMfTvdehbzE91cAfwLtjeKzIMpIKVMQZ5L9JqqKhg8Uj5iUPQRqDUMShU+QNwl5aw+/gVmvZk7bAJ6fCpSsfkEztlqlIEt6eSB2FMXdIhQkytN8k9pEkzXBvvlI9rAc7XO54zRy9xt4Y0k7IIbr1c+Gi6vQJ6L8dx+VjdtdXH2Qofy+8CZuiwA6sjDB0ZKdXVipKUCkGaihsZhxoU+/kKWe2CGr7o/W63ZFI6sqKevRDjBziQimdJj6PahDbQ5nutle4vIaYxKyCW8bCBMijEeqRelY/eoYWZgdJCAYIwVbGVPW3d7UBrAgMBAAECggEBAJtfkxf4T4iblCmteVfb4aVHiQfJwc18VEYy2qkgvOoRhmMx4mv/sKNscGoMIXwMj0U6lQ/r8D8PnmzWBeEYrVslxQ9PYw3xm+y0z+qVxTTpiHBi08L8j0HHMaZbLBtVly6mQOKzrB/fJafXfmQXXRfXbTywH+2UZqb+oiFRTTzEnFMyku5HquA27Mp+K4KNFTVaKiCSadwz+XyFOf1cmUn4oRlYnhgbMKgn2JSyQLfJ5SSgYhnxat1Qbg1HDhOzo6L/NQwCkTzo3B52X56EQXZkk2p1pVRZiwaP/3FCHEenOv9jy+ZffdUFECRCv0Aw2isWqZ4zuVrgWCI801W/AVECgYEA0gwkMSHWlJaGtWhYifgWcOSr/v9l/SAiD0VN57j4THWIAq30WtOVE/ta4XhbSasxcHJIqNckq2inEm2b3jwcS7YKzlfKGl9xw8uL3yVM1YXtKwGrJr1xk8pcWOVBmFaAd8BaOHwsMkE8EhgiwZSctTbmRNeiOz6lIOj2aDu6fE0CgYEAz5SPKeNay00LIGk4Os+Zev1JPhwW4tfwTJxXV97TjvgYoRwUwV6XNjiXoxQD5iOXieK7Cy0GDMzJWxXpmEpI5BVv2X6GMkkH5iXz4rGtzsMNWZ5lF3d2PpRLvRIrSi3btevTohN7UkogyjEPhuEnV47Emsev36lB+bcJwgLBK5cCgYAuEaemdwt/T3yAMUCqEhWp8R2gMhgGapPN0Z+CoVkkO+r223xqp1ldJpYKOcGb6MZRKV+yWG2cgrmSGyRCm+CA4o6AL1UOb7yd+vjUmnO9qUAZXKZTOt28Unfqr22xoddPbIrdNK7k3tX0CgMlfhjYzg+3LaxRXi4Nh8rzlZYTSQKBgBahgq41bEun3aOt9QRsZ7ZB8P9FfrVCh59CmD8rOvNmVwERl62xS1kM+HM+FmK71KSixHOmd/djSDyW+f2xc5ryP1x979GBpsvPrXQ0nNdi6oyvuSPC0XBnKI63cWLH9yExUcRkzVgeXs7MZH33BBwGo6agSKtgv6Gi8/xj4n2HAoGBALD55ZzDDrB17ZOQSuEnn45R3FA62BGipCM8HFdZySeEOf9IPoOxy2xmzQtMc2VESRQeviw92E5gxNxrRgIHSQvPJryaHOjoMKI9+kDBejZvBEHWi23E4tobPUOUH/jBJJQ7Ue5aRB6IS/jlMzmVhan8vefnEXRDT5EnSfxV3Pa6";
    //客户端公钥
    public static final String CLIENT_PUBLIC_KEY="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApRAKdDQx7W/cOYiX8jToeg3gkb9EYxhQNQiEOmcaXyHOuYdN4VBrA43GbVkEGX+3d9IYlQnEC8pSWCYnR0Gz3A1lC0YTm4FMRSBUN+1FvHPAxw4hzzVUYx+O3j4vbGSGG1bmljiZEvTQKEg00QwNb0u3sFqLAPVslEhLlkhJunkEFdNp5YX/3CLLt24g5qvGPX34PZS4BGGx+FULum0V4KqcvdDsRYdyYdep2wGV6gCTCgmciWKOQfWTeDaPEPxDGXvfAzRcmzqHe1k7kJq0uRTNLwrI0KXMwcJ/nZ8uYK1peGIFGIAFjp7z69ojF1Vy6m0I3FRDBSsK/+9SvclXoQIDAQAB";
 
}

package com.kinglong.http.controller;
 
import com.kinglong.http.constans.Constans;
import com.kinglong.http.rto.ResponseObject;
import com.kinglong.http.utils.MyRSAUtils;
import com.kinglong.http.utils.SignUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
 
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
 
@Controller
public class HttpController {
 
    @RequestMapping("/api/verifydemo")
    @ResponseBody
    public Object demo(@RequestParam(value = "realName")String realName,
                           @RequestParam(value = "phone")String phone,
                           @RequestParam(value = "idCard")String idCard,
                           @RequestParam(value = "bankCard")String bankCard,
                           @RequestParam(value = "sign")String sign){
 
        ResponseObject responseObject = new ResponseObject();
        Map<String,Object> map = new ConcurrentHashMap<String,Object>();
 
    //签名参数验证
        if (StringUtils.isEmpty(realName)){
 
            responseObject.setErroMessage("真实姓名不能为空");
            responseObject.setCode("0000");
 
        }else if (StringUtils.isEmpty(phone)){
 
            responseObject.setErroMessage("手机号不能为空");
            responseObject.setCode("0000");
 
        }else if (StringUtils.isEmpty(idCard)){
 
            responseObject.setErroMessage("身份证不能为空");
            responseObject.setCode("0000");
 
        }else if (StringUtils.isEmpty(bankCard)){
 
            responseObject.setErroMessage("银行卡不能为空");
            responseObject.setCode("0000");
 
        }else if (StringUtils.isEmpty(sign)){
 
            responseObject.setErroMessage("签名不能为空");
            responseObject.setCode("0000");
 
        }else {
                //封装参数进行验证
                map.put("realName",realName);
                map.put("phone",phone);
                map.put("idCard",idCard);
                map.put("bankCard",bankCard);
 
        //注意看,这里使用的就是客户端的公钥进行签名的解密
               boolean isTrue = MyRSAUtils.signVerify(sign,SignUtils.generateSortSign(map),Constans.CLIENT_PUBLIC_KEY);
 
                if (!isTrue){
 
                    responseObject.setErroMessage("签名有误,请核查后再次尝试");
                    responseObject.setCode("0000");
            }
        }
 
        //0000是失败,1111是成功
        String code = responseObject.getCode();
        if(code!=null && code.equals("0000")){
 
            map.clear();
            map.put("result","0000");
            map.put("resultDesc",responseObject.getErroMessage());
        
        //使用服务端私钥生成返回的签名
            String ret_sign = MyRSAUtils.sign(SignUtils.generateSortSign(map),Constans.SERVER_PRIVATE_KEY);
            map.put("ret_sign",ret_sign);
            responseObject.setObject(map);
 
        }else {
 
            map.clear();
            map.put("result","ok");
            map.put("resultDesc","验证通过");
 
        //使用服务端私钥生成返回的签名
            String ret_sign = MyRSAUtils.sign(SignUtils.generateSortSign(map),Constans.SERVER_PRIVATE_KEY);
            map.put("ret_sign",ret_sign);
            responseObject.setObject(map);
            responseObject.setCode("1111");
            responseObject.setErroMessage("验证成功");
 
        }
 
        return responseObject;
    }
 
}

目录
相关文章
|
12天前
|
JSON API 数据格式
淘宝 / 天猫官方商品 / 订单订单 API 接口丨商品上传接口对接步骤
要对接淘宝/天猫官方商品或订单API,需先注册淘宝开放平台账号,创建应用获取App Key和App Secret。之后,详细阅读API文档,了解接口功能及权限要求,编写认证、构建请求、发送请求和处理响应的代码。最后,在沙箱环境中测试与调试,确保API调用的正确性和稳定性。
|
24天前
|
供应链 数据挖掘 API
电商API接口介绍——sku接口概述
商品SKU(Stock Keeping Unit)接口是电商API接口中的一种,专门用于获取商品的SKU信息。SKU是库存量单位,用于区分同一商品的不同规格、颜色、尺寸等属性。通过商品SKU接口,开发者可以获取商品的SKU列表、SKU属性、库存数量等详细信息。
|
25天前
|
JSON API 数据格式
店铺所有商品列表接口json数据格式示例(API接口)
当然,以下是一个示例的JSON数据格式,用于表示一个店铺所有商品列表的API接口响应
|
1月前
|
编解码 监控 API
直播源怎么调用api接口
调用直播源的API接口涉及开通服务、添加域名、获取API密钥、调用API接口、生成推流和拉流地址、配置直播源、开始直播、监控管理及停止直播等步骤。不同云服务平台的具体操作略有差异,但整体流程简单易懂。
|
15天前
|
JSON API 数据安全/隐私保护
拍立淘按图搜索API接口返回数据的JSON格式示例
拍立淘按图搜索API接口允许用户通过上传图片来搜索相似的商品,该接口返回的通常是一个JSON格式的响应,其中包含了与上传图片相似的商品信息。以下是一个基于淘宝平台的拍立淘按图搜索API接口返回数据的JSON格式示例,同时提供对其关键字段的解释
|
1月前
|
Kubernetes 安全 Cloud Native
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
本文介绍了云原生环境下Kubernetes集群的安全问题及攻击方法。首先概述了云环境下的新型攻击路径,如通过虚拟机攻击云管理平台、容器逃逸控制宿主机等。接着详细解释了Kubernetes集群架构,并列举了常见组件的默认端口及其安全隐患。文章通过具体案例演示了API Server 8080和6443端口未授权访问的攻击过程,以及Kubelet 10250端口未授权访问的利用方法,展示了如何通过这些漏洞实现权限提升和横向渗透。
159 0
云上攻防-云原生篇&K8s安全-Kubelet未授权访问、API Server未授权访问
|
1月前
|
人工智能 自然语言处理 PyTorch
Text2Video Huggingface Pipeline 文生视频接口和文生视频论文API
文生视频是AI领域热点,很多文生视频的大模型都是基于 Huggingface的 diffusers的text to video的pipeline来开发。国内外也有非常多的优秀产品如Runway AI、Pika AI 、可灵King AI、通义千问、智谱的文生视频模型等等。为了方便调用,这篇博客也尝试了使用 PyPI的text2video的python库的Wrapper类进行调用,下面会给大家介绍一下Huggingface Text to Video Pipeline的调用方式以及使用通用的text2video的python库调用方式。
|
1月前
|
JSON JavaScript API
(API接口系列)商品详情数据封装接口json数据格式分析
在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦!
|
25天前
|
JSON 前端开发 JavaScript
API接口商品详情接口数据解析
商品详情接口通常用于提供特定商品的详细信息,这些信息比商品列表接口中的信息更加详细和全面。以下是一个示例的JSON数据格式,用于表示一个商品详情API接口的响应。这个示例假定API返回一个包含商品详细信息的对象。
|
1月前
|
JSON API 开发者
1688API商品详情接口如何获取
获取 1688 API 商品详情接口的步骤包括:1. 注册开发者账号;2. 了解接口规范和政策;3. 申请 API 权限;4. 获取 API 密钥;5. 实现接口调用(选择开发语言、发送 HTTP 请求);6. 处理响应数据。通过这些步骤,可以顺利调用 1688 的商品详情 API。
下一篇
无影云桌面