meta:
- name: 土豆API文档 content: 土豆API文档
- name: keywords content: 土豆API文档
# 请仔细阅读
- 请严格按照接口文档开发,有问题请联系工作人员,或下载实例查看学习代码,接口支持base64加密,AEC加密,DES加密,AES加密,RC4加密,接口验签,IP限制等..在登录土豆API后APP设置里面均可配置,严禁用于非法用途,违规者将给予封号惩罚,一切解释权归
土豆API
所有
# 接口验证方式
- 接口支持post,get方式请求(未标注是哪个接口表示都可以),任何接口请求必须携带askKey(askKey详见),部分接口需要携带apiUserToken(apiUserToken详见),接口支持form-data,x-www-form-urlencoded,json等格式请求,如果开启加密时,不需要对key进行加密,需要对value进行对应加密,使用加密时,建议不要使用get请求,否则会出现加密后的数据被转码而导致服务端解密失败
# 接口验签
- 接口验签,建议加上,可防止非法抓包破解接口,这是一种验证接口是否客户端请求,非客户端会提示验签失败,签名使用的是北京时间,签名参数放需要在请求头,如果开启验签,响应的签名会放在参数内,土豆API响应内容也会返回验签数据,
客户端可以自行验签
,保证数据安全性
# 验签规则V1
验签规则为 验签字符串+时间戳,再将其进行md5算法加密(32位),请求头上需要携带时间戳和加密后的字符串时间戳key为time,加密后的字符串的key为sign,如果开启验签,土豆API响应内容也会返回验签数据,客户端可以自行验签
,保证数据安全性
验签算法:
sign=md5算法加密后的您的验签字符串+当前系统时间戳(毫秒)
time=当前系统时间戳(毫秒)
javascript demo
/**
*
* @param {*} signSecretKey 验签秘钥
* @param {*} timestamp 时间戳
* @returns
*/
function signV1(signSecretKey, timestamp) {
return md5(signSecretKey + timestamp)
}
2
3
4
5
6
7
8
9
java demo
/**
* @param time 时间戳
* @param signSecretKey 验签秘钥
* @return
*/
public static String signApiV1Sign(String time,String signSecretKey){
String s = DigestUtils.md5DigestAsHex((signSecretKey+time).getBytes());
return s;
}
2
3
4
5
6
7
8
9
10
lua demo
local md5 = require("md5")
-- 定义函数signApiV1Sign
function signApiV1Sign(time, signSecretKey)
-- 将验签秘钥和时间戳拼接成字符串
local strToHash = signSecretKey.. time
-- 计算MD5并返回十六进制格式的结果
local result = md5.sumhexa(strToHash)
return result
end
2
3
4
5
6
7
8
9
10
# 验签规则V2
验签V2相对于V1会对请求的参数进行加密,再将其进行md5算法加密(32位)
验签Demo:
sign=md5算法加密后的您的验签字符串+当前系统时间戳(毫秒)
time=当前系统时间戳(毫秒)
javascript demo
/**
*
* @param {*} signSecretKey 验签秘钥
* @param {*} timestamp 时间戳
* @param {*} data 请求数据
* @returns
*/
function signV2(signSecretKey, timestamp, data) {
const map = new Map(Object.entries(data));
const sortedKeys = Array.from(map.keys()).sort();
var resultSign = ''
sortedKeys.forEach(key => {
resultSign = resultSign + '&' + key + '=' + map.get(key)
});
resultSign = resultSign + '&' + signSecretKey + '&' + timestamp
return md5(resultSign)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
java demo
/**
* @param time 时间戳
* @param signSecretKey 验签秘钥
* @param param 数据
* @return
*/
public static String signApiV2Sign(String time,String signSecretKey, Map<String, String> param){
// 进行排序
TreeMap<String,String> treeMap=new TreeMap<>();
treeMap.putAll(param);
Set<String> strings = treeMap.keySet();
StringBuilder sb=new StringBuilder();
for (String string : strings) {
sb.append("&")
.append(string)
.append("=")
.append(treeMap.get(string));
}
sb.append("&")
.append(signSecretKey)
.append("&")
.append(time);
String s = DigestUtils.md5DigestAsHex((sb.toString()).getBytes());
return s;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
lua demo
-- 定义signV2函数
function signV2(signSecretKey, timestamp, data)
local map = {}
-- 将表数据转换为类似Map的结构,这里简单用Lua表来模拟
for key, value in pairs(data) do
map[key] = value
end
-- 获取所有的键并进行排序
local sortedKeys = {}
for key in pairs(map) do
table.insert(sortedKeys, key)
end
table.sort(sortedKeys)
local resultSign = ""
-- 拼接字符串
for _, key in ipairs(sortedKeys) do
resultSign = resultSign.. "&".. key.. "=".. map[key]
end
resultSign = resultSign.. "&".. signSecretKey.. "&".. timestamp
-- 计算md5并返回结果
return md5.sumhexa(resultSign)
end
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 验签规则V3
V3相对于V2更安全,添加了随机字符串nonce
,随机字符串在2分钟内不允许重复使用,否则会提示验签失败,nonce会在生成待签名数据最后面拼接该参数
验签Demo:
javascript demo
/**
*
* @param {*} signSecretKey 验签秘钥
* @param {*} timestamp 时间戳
* @param {*} data 请求数据
* @param {*} nonce 随机字符串
* @returns
*/
function signV3(signSecretKey, timestamp, data, nonce) {
const map = new Map(Object.entries(data));
const sortedKeys = Array.from(map.keys()).sort();
var resultSign = ''
sortedKeys.forEach(key => {
resultSign = resultSign + '&' + key + '=' + map.get(key)
});
resultSign = resultSign + '&' + signSecretKey + '&' + timestamp + 'nonce' + nonce
return md5(resultSign)
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
java demo
/**
* @param time 时间戳
* @param signSecretKey 验签秘钥
* @param param 数据
* @param nonce 随机字符串
* @return
*/
public static String signApiV3Sign(String time, String signSecretKey, Map<String, String> param, String nonce){
// 进行排序
TreeMap<String,String> treeMap=new TreeMap<>();
treeMap.putAll(param);
Set<String> strings = treeMap.keySet();
StringBuilder sb=new StringBuilder();
for (String string : strings) {
sb.append("&")
.append(string)
.append("=")
.append(treeMap.get(string));
}
sb.append("&")
.append(signSecretKey)
.append("&")
.append(time)
.append("&")
.append(nonce);
String s = DigestUtils.md5DigestAsHex((sb.toString()).getBytes());
return s;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
lua demo
local md5 = require("md5")
-- 定义函数signApiV3Sign
function signApiV3Sign(time, signSecretKey, param, nonce)
-- 使用table库的功能来模拟类似Java中TreeMap的有序结构,这里创建一个空表来存储有序数据
local treeMap = {}
-- 将传入的param表中的数据复制到treeMap中,以实现类似putAll的操作
for key, value in pairs(param) do
treeMap[key] = value
end
-- 获取所有的键,用于后续构建字符串
local keys = {}
for key in pairs(treeMap) do
table.insert(keys, key)
end
-- 对键进行排序,模拟TreeMap的有序特性
table.sort(keys)
-- 构建用于计算MD5的字符串
local sb = ""
for _, key in ipairs(keys) do
sb = sb.. "&".. key.. "=".. treeMap[key]
end
sb = sb.. "&".. signSecretKey.. "&".. time.. "&".. nonce
-- 计算MD5并返回十六进制格式的结果,这里使用lua-md5库的sumhexa函数来实现,不同库可能有差异
local result = md5.sumhexa(sb)
return result
end
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 加解密规则
请求加密,请求加密规范,请求内容为半加密,需要以key-加密(value),方式请求,其中加密(value)指的是加密算法加密后的值,其中key不需要加密,土豆API给予响应内容,为全加密
正确加密请求实例
实例接口/api/login
请求
{
"userNumber":"MTIzNDc=",
"passWord":"MTIzNDU2"
}
响应内容:
eyJjb2RlIjoiMjAwIiwibWVzc2FnZSI6IiIsInN0YXR1cyI6dHJ1ZSwiZGF0YSI6eyJhcGlVc2VyVG9rZW4iOiJleUowZVhBaU9pSktWMVFpTENKaGJHY2lPaUpJVXpJMU5pSjkuZXlKamRYSnlaVzUwSWpveE5qWTBPVE0wTlRrNU9UTXpMQ0pWVTBWU1ZHOXJaVzVMWlhraU9pSTJPVEUwTlRJNE1UWTRNRFU0TnprNE1EaGZNVEl6TkRjaUxDSjFjMlZ5U1dRaU9qWTVNVFExTWpneE5qZ3dOVGczT1Rnd09Dd2lkWE5sY2s1MWJXSmxjaUk2SWpFeU16UTNJbjAuR0VJMldjWF85TjhuT21fZURxelQyclJzOUJfeXAwcms3aTdHVGFXS3dUQSJ9LCJwYyI6bnVsbCwidGltZSI6bnVsbCwic2luIjpudWxsfQ==
2
3
4
5
6
7
错误加密请求实例
实例接口/api/login
请求
{
"userNumber":"12347",
"passWord":"123456"
}
响应内容:
eyJjb2RlIjoiNTAwIiwibWVzc2FnZSI6IuaVsOaNruino+WvhuWksei0pSIsInN0YXR1cyI6ZmFsc2V9
2
3
4
5
6
7
# 注意
注意,后端http状态码为500时,一般表示为请求数据解析失败或者请求数据解密失败,或者系统错误, 如果http状态码为500,当然解密失败情况只会出现在开发阶段,正式阶段出现加解密异常则为开发者更换了秘钥导致,返回报文为明文数据对象, 开发者可以直接获取数据,如果是业务类型错误,比如用户余额不足,返回的http状态码为200, 错误信息为密文,开发者使用对应解密方法解密数据即可, 凡是上传文件的接口均不支持加解密(不包含base64),后续优化该功能
解密失败请求实例
实例接口api/updateUserBalance
请求:
{
"type":12,
"amount":10
}
2
3
4
响应内容: 此时http状态码为500,不是返回数据码,这点请注意
数据解密失败报文:
{
"timestamp": 1676518671836,
"status": 500,
"error": "Internal Server Error",
"message": "数据解密失败",
"path": "/api/updateUserBalance"
}
数据解析失败报文:
{
"timestamp": 1676519332339,
"status": 500,
"error": "Internal Server Error",
"message": "内容解析失败,请检查提交信息是否正确",
"path": "/api/updateUserBalance"
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 请求生产环境地址,下文的baseUrl
https://api.potatocloud.cn
# 请求URL(baseUrl+接口URL)
{baseUrl}/api/test
- 举例
https://api.potatocloud.cn/api/test
# 请求方式
- POST | GET | DELETE | PUT
# 请求头参数
参数名 | 必选 | 类型 | 说明 |
---|---|---|---|
Content-Type | 是 | string | 此参数必传,当请求数据非json时此参数传对应格式如(multipartform-data,application/x-www-form-urlencoded,等)是json请传application/json |
askKey | 是 | string | 此参数必传,验证app的令牌 |
sign | 否 | string | 此参数如果在app设置开启了验签是必传,规则上方有描述 |
time | 否 | string | 当开启验签时,此参数为必传 |
apiUserToken | 否 | string | 除了部分不验证用户令牌的接口以外此参数为必传(注册/登陆/发送验证码 )不是必传,其余都是必传 |
# 接口参数
接口参数每个接口文档有详细的参数描述
# 返回示例
{
"code": "200",
"message": "",
"status": true,
"data": null,
"pc": null,
"time": null,
"sign": null,
"nonce": null
}
2
3
4
5
6
7
8
9
10
11
# 返回参数说明
参数名 | 类型 | 说明 |
---|---|---|
code | string | 200请求成功,403无权限或令牌过期,返回该状态码建议跳转登陆界面让用户进行重新登陆500为错误,message会携带错误信息返回,可以将该详细提示给用户 |
message | string | 错误信息,成功是不会返回错误信息 |
status | boolean | 状态,true 为成功,false 为失败 |
data | json | 返回数据 格式为json,如果需要返回数据时候,该参数会携带数据返回 |
pc | json | 分页对象,携带分页信息,如果不是列表查询该参数为null |
time | String | 时间戳(开启验签时返回不为空) |
sign | String | 签名(开启验签时返回不为空) |
nonce | String | 随机字符串(开启验签V3时返回不为空) |
# 备注
# OCR识别
OCR支持中,英文,以及数字,其他字库联系官方添加 如果OCR识别不支持PNG后缀直接改成jpg这种类型文件,如果出现该情况,请保存新的图像上传识别,由于字库是使用默认字库,如需识别特殊字符可以联系官方训练字库,
- 更多返回错误代码请看首页的错误代码描述
关于我们 →