个验服务端接入文档

个验服务端接入文档

接口说明

动画验证码

1 【动画验证码】二次验证接口

1.1 接口说明

业务方携带动画验证码校验成功后的validate来调用此接口进行二次验证。validate在一段时间内有效,接口IP需要配置IP白名单。

请求地址:https://openapi-gy.getui.com/v1/gy/captcha/verify

协议:HTTPS

请求方法:POST+json

1.2 参数说明

请求参数
参数 类型 约束 说明
appId String 必选 业务在个验申请的应用id
gyuid String 必选 个验用户唯一标识
businessId String 必选 动画验证码业务id
validate String 必选 动画验证码验证结果查询凭证
timestamp Long 必选 时间戳
sign String 必选 接口签名,生成规则:
1. 筛选:获取所有非空参数值的请求参数,不包括字节类型参数,如文件、字节流,剔除sign参数。
2. 排序:将筛选的参数按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。
3. 拼接:将排序后的参数与其对应值,使用URL键值对的格式(即key1=value1&key2=value2…)拼接,此时生成的字符串为待签名字符串。将待签名字符串拼上“&key=${masterSecret}”,带入SHA256算法中得出sign。
响应参数
参数 层级 类型 约束 说明
errno 1 Int 必选 固定值 0
data 1 Object 必选
msg 2 String 必选 接口返回码说明
result 2 String 必选 接口返回码
data 2 Object 可选
verifyResult 3 Boolean 可选 二次验证结果, true:成功 false:失败

1.3 示例

请求示例
{
    "appId": "LLNstWgyGm8UM2SsherlU5",
    "gyuid": "83f0f7e943484e3ca58fccc2f3d1e48777",
    "businessId": "20180523",
    "validate": "6a2cab5c0abc06ea9a1503ff4eb619d1",
    "timestamp": 1529391652123,
    "sign": "9f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab515ab7d1"
}
返回示例
{
    "errno": "0",
    "data": {
        "result": "20000",
        "msg": "成功",
        "data": {
            "verifyResult": true,
        }
    }
}

1.4 返回码说明

接口返回码说明
返回码 返回码描述
20000 接口调用成功
40004 应用无效,应用不存在
40005 appid为空
40009 未知错误
40031 IP受限
40032 参数错误
50000 未知错误
50001 其他错误
60001 业务ID无效
60002 请求过快
60004 无权限
60008 sign验证失败

反欺诈

2 【反欺诈】注册保护、登录保护二次校验

2.1 接口说明

业务方携带反欺诈接口返回的token来调用此接口获取反欺诈结果,进行二次校验。token在一段时间内有效,接口需要配置IP白名单。

请求地址:https://openapi-gy.getui.com/v1/af/antifraud_query

协议:HTTPS

请求方法:POST+json

2.2 参数说明

请求参数
参数 类型 约束 说明
appId String 必选 业务在个验申请的应用id
gyuid String 必选 个验用户唯一标识
token String 必选 查询反欺诈结果凭证
timestamp Long 必选 时间戳
sign String 必选 接口签名,生成规则:SHA256(appId + gyuid + token + timestamp + masterSecret)
响应参数
参数 层级 类型 约束 说明
errno 1 Int 必选 固定值 0
data 1 Object 必选
msg 2 String 必选 接口返回码说明
result 2 String 必选 接口返回码
data 2 Object 可选
riskLevel 3 String 可选 分为0-4共5个等级,0代表可信用户,1-2代表怀疑用户,3-4代表风险用户
riskType 3 Array 可选 1:帐号风险,2:网络风险,3:设备风险,4:行为风险

2.3 示例

请求示例
{
    "appId": "LLNstWgyGm8UM2SsherlU5",
    "gyuid": "83f0f7e943484e3ca58fccc2f3d1e48777",
    "token": "6a2cab5c0abc06ea9a1503ff4eb619d1",
    "timestamp": 1529391652123,
    "sign": "9f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab515ab7d1"
}
返回示例
{
    "errno": "0",
    "data": {
        "result": "20000",
        "msg": "成功",
        "data": {
            "riskLevel": "1",
            "riskType": ["1"],
        }
    }
}

2.4 返回码说明

接口返回码说明
返回码 返回码描述
20000 成功
40004 应用无效,应用不存在
40005 appid为空
40009 未知错误
40031 IP受限
40032 参数错误
40033 请求过快,请稍后再试
40036 无权限
40041 token失效
40044 sign验证失败
50000 未知错误
50001 其他错误

3 【反欺诈】反欺诈通用查询接口

3.1 接口说明

业务方服务端在获取gyuid后,可通过gyuid定期按需获取设备风险信息。接口需配置IP白名单。

请求地址:https://openapi-gy.getui.com/v1/af/antifraud

协议:HTTPS

请求方法:POST+json

3.2 参数说明

请求参数
参数 类型 约束 说明
appId String 必选 业务在个验申请的应用id
gyuid String 必选 个验用户唯一标识
userIp String 可选 用户ip
pn String 可选 手机号码MD5
scene Integer 必选 场景,0:通用,1:注册,2:登录
timestamp Long 必选 时间戳
sign String 必选 1. 筛选:获取所有非空参数值的请求参数,不包括字节类型参数,如文件、字节流,剔除sign参数。
2. 排序:将筛选的参数按照第一个字符的键值ASCII码递增排序(字母升序排序),如果遇到相同字符则按照第二个字符的键值ASCII码递增排序,以此类推。
3. 拼接:将排序后的参数与其对应值,使用URL键值对的格式(即key1=value1&key2=value2…)拼接,此时生成的字符串为待签名字符串。将待签名字符串拼上“&key=${masterSecret}”,带入SHA256算法中得出sign。
响应参数
参数 层级 类型 约束 说明
errno 1 Int 必选 固定值 0
data 1 Object 必选
msg 2 String 必选 接口返回码说明
result 2 String 必选 接口返回码
data 2 Object 可选
riskLevel 3 String 可选 分为0-4共5个等级,0代表可信用户,1-2代表怀疑用户,3-4代表风险用户
riskType 3 Array 可选 1:帐号风险,2:网络风险,3:设备风险,4:行为风险

3.3 示例

请求示例
{
    "appId": "LLNstWgyGm8UM2SsherlU5",
    "gyuid": "83f0f7e943484e3ca58fccc2f3d1e48777",
    "scene": 1,
    "timestamp": 1529391652123,
    "sign": "9f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab515ab7d1"
}
返回示例
{
    "errno": "0",
    "data": {
        "result": "20000",
        "msg": "成功",
        "data": {
            "riskLevel": "1",
            "riskType": ["1"],
        }
    }
}

3.4 返回码说明

接口返回码说明
返回码 返回码描述
20000 成功
40004 应用无效,应用不存在
40005 appid为空
40009 未知错误
40031 IP受限
40032 参数错误
40033 请求过快,请稍后再试
40034 今日验证次数超限
40036 无权限
40044 sign验证失败
50000 未知错误
50001 其他错误

一键认证

4 【一键认证】获取登录信息接口(逐渐停用)

4.1 接口说明

业务方调用此接口获取登录信息,参数token是来自于SDK端调用一键认证之后返回的用户授权凭证信息。token在一段时间内有效,接口IP需要配置IP白名单。此接口将逐渐停用,请尽快更新至v2版接口

请求地址:https://openapi-gy.getui.com/v1/gy/ct_login/gy_get_pn

协议:HTTPS

请求方法:POST+json

4.2 参数说明

请求参数
参数 类型 约束 说明
appId String 必选 业务在个验申请的应用id
timestamp Long 必选 时间戳
sign String 必选 接口签名,生成规则:SHA256(appKey + timestamp + masterSecret)
token String 必选 调用SDK上传token返回的凭证 (默认是10分钟的失效时间)
gyuid String 必选 调用
响应参数
参数 层级 类型 约束 说明
errno 1 Int 必选 固定值 0
data 1 Object 必选
msg 2 String 必选 接口返回码说明
result 2 String 必选 接口返回码
data 2 Object 可选
pn 3 String 可选 运营商返回的号码

4.3 示例

请求示例
{
    "appId": "LLNstWgyGm8UM2SsherlU5",
    "timestamp": 1529391652123,
    "gyuid":"12313ssad",
    "sign": "8f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab517d1",
    "token": ""
}
返回示例
{
    "errno": "0",
    "data": {
        "result": "20000",
        "msg": "成功",
        "data": {
            "pn": "1xxxxxxxxxx",
        }
    }
}

4.4 返回码说明

接口返回码说明
返回码 返回码描述
20000 接口调用成功
40004 应用无效,应用不存在
40005 appid为空
40009 未知错误
40026 签名错误
40027 获得auth_token失败
40031 IP受限
40032 参数错误
40033 请求过快,请稍后再试
40034 今日次数超限
50000 未知错误
50001 其他错误
50002 未知错误

5 【一键认证】密文获取登录信息接口

5.1 接口说明

业务方调用此接口获取登录信息,参数token是来自于SDK端调用一键认证之后返回的用户授权凭证信息。token在一段时间内有效,接口IP需要配置IP白名单。
:返回的用户信息采用AES加密,密钥为应用对应的masterSecret,算法参考5.5(直接下载: JavaPHPPythonNodeJs)。v1版获取登录信息接口将逐渐停用

请求地址:https://openapi-gy.getui.com/v2/gy/ct_login/gy_get_pn

协议:HTTPS

请求方法:POST+json

5.2 参数说明

请求参数
参数 类型 约束 说明
appId String 必选 业务在个验申请的应用id
timestamp Long 必选 时间戳
sign String 必选 接口签名,生成规则:SHA256(appKey + timestamp + masterSecret)
token String 必选 调用SDK上传token返回的凭证 (默认是10分钟的失效时间)
gyuid String 必选 调用
响应参数
参数 层级 类型 约束 说明
errno 1 Int 必选 固定值 0
data 1 Object 必选
msg 2 String 必选 接口返回码说明
result 2 String 必选 接口返回码
data 2 Object 可选
pn 3 String 可选 AES加密的手机号,密钥为应用对应的masterSecret

5.3 示例

请求示例
{
    "appId": "LLNstWgyGm8UM2SsherlU5",
    "timestamp": 1529391652123,
    "gyuid":"12313ssad",
    "sign": "8f8ef776b7364c96fc1a7e734976e32b6a5e297a1ddbaea31bf3deab517d1",
    "token": ""
}
返回示例
{
    "errno": "0",
    "data": {
        "result": "20000",
        "msg": "成功",
        "data": {
            "pn": "1fbf2605f954fad3ba18115000735aee",
        }
    }
}

5.4 返回码说明

接口返回码说明
返回码 返回码描述
20000 接口调用成功
40004 应用无效,应用不存在
40005 appid为空
40009 未知错误
40026 签名错误
40027 获得auth_token失败
40031 IP受限
40032 参数错误
40033 请求过快,请稍后再试
40034 今日次数超限
50000 未知错误
50001 其他错误
50002 未知错误

5.5 AES解密说明

Java AES解密算法示例
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * Date: 2019/12/18
 * Description: AES解密
 * */
public class AESUtil{

    private static final String KEY_ALGORITHM = "AES";
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";//加密算法
    private static final byte[] IV = "0000000000000000".getBytes(); //初始化向量

    /**
     * AES 解密操作
     *
     * @param content 待解密内容
     * @param key 加密密钥
     * @return 解密数据
     * */
    public static String decrypt(String content, String key) {
        try {
            // 创建密码器
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            // 配置密码器
            IvParameterSpec ivSpec = new IvParameterSpec(IV);
            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(key), ivSpec);
            // 解密
            byte[] result = cipher.doFinal(hex2Bytes(content));
            // 格式化输出
            return new String(result, StandardCharsets.UTF_8);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取密钥,取前16位,不足则复制
     *
     * @param key 用户密钥
     * @return KeySpec对象
     * */
    private static SecretKeySpec getSecretKey(String key) {
        if(key==null || key.isEmpty()){
            return null;
        }
        StringBuilder s = new StringBuilder(key);
        while(s.length() < 16){
            s.append(key);
        }
        return new SecretKeySpec(s.substring(0,16).getBytes(), KEY_ALGORITHM);
    }

    /**
     * hex字符串转byte数组
     *
     * @param hex 待转换的hex字符串
     * @return  转换后的byte数组
     * */
    private static byte[] hex2Bytes(String hex){
        if (hex.length() % 2 == 1){
            hex="0" + hex;
        }
        byte[] result = new byte[hex.length()/2];
        for (int i = 0; i < result.length; i++){
            result[i] = (byte)Integer.parseInt(hex.substring(2*i,2*i+2), 16);
        }
        return result;
    }

    public static void main(String[] args) {
        String pn = "1fbf2605f954fad3ba18115000735aee"; //密文
        String masterSecret = "126781";                 //密钥
        System.out.println("解密后:" + AESUtil.decrypt(pn, masterSecret));
    }
}
PHP AES解密算法示例
// 密文及密钥
$pn = '1fbf2605f954fad3ba18115000735aee';
$masterSecret = '126781';

// 参数设置
$encryptMethod = 'aes-128-cbc';
$iv = '0000000000000000';

// 取16位密钥
$key = $masterSecret;
while(strlen($key) < 16){
    $key .= $masterSecret;
}
$key = substr($key, 0, 16);

// 解密
$result = openssl_decrypt(hex2bin($pn), $encryptMethod, $key, 1, $iv);
echo $result;
Python AES解密算法示例
# pip3 install pycryptodome
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

def decrypt(content, secret):
    # 参数设置
    iv = b'0' * 16

    # 取16位密钥
    key = secret
    while len(key) < 16:
        key += secret
    key = key[0:16]

    # 解密
    cipher = AES.new(key.encode(), AES.MODE_CBC, iv)
    result = unpad(cipher.decrypt(bytes.fromhex(content)), 16)
    return result.decode()

if __name__ == '__main__':
    pn = '1fbf2605f954fad3ba18115000735aee'    # 密文
    master_secret = '126781'                   # 密钥
    print(decrypt(pn, master_secret))
NodeJs AES解密算法示例
var CryptoJS = require("crypto-js");

function decrypt(content, secret){
    // 参数设置
    var iv = "0000000000000000";

    // 取16位密钥
    var key = secret;
    while(key.length < 16){
        key += secret;
    }
    key = key.substr(0, 16);

    // 解密
    var en = Buffer.from(content, 'hex').toString("base64");
    var result = CryptoJS.AES.decrypt(en, CryptoJS.enc.Utf8.parse(key), {
        iv:CryptoJS.enc.Utf8.parse(iv),
        mode:CryptoJS.mode.CBC,
        padding:CryptoJS.pad.Pkcs7
    });
    return result.toString(CryptoJS.enc.Utf8);
}

// 密文及密钥
var pn = "1fbf2605f954fad3ba18115000735aee";
var masterSecret = "126781";
console.log(decrypt(pn, masterSecret));

如需其它语言示例,请联系技术支持 QQ:3007288195

文档中心搜索