小游戏签名说明文档

URL编码算法 urlencode

签名验证时,要求对字符串中除了“-”、“_”、“.”之外的所有非字母数字字符都替换成百分号(%)后跟两位十六进制数。 十六进制数中字母必须为大写。

 var urlencode = function(str){
    var res = encodeURIComponent(str);

    //0~9 a~z A~Z -_.
    res = res.replace(/[^0-9a-zA-Z\-_\.%]/g, function ($0) {
        //不用考虑一位数了
        return '%' + $0.charCodeAt(0).toString(16).toUpperCase();
    });

    return res;
};

构造源串

源串是由3部分内容用“&”拼接起来的: HTTP请求方式 & urlencode(uri) & urlencode(a=x&b=y&...)

(由于是通用说明,这里以/v3/user/get_info作为示例,且示例中的请求串不可直接复制访问)

  1. 原始请求信息:

    appkey:228bf094169a40a3bd188ba37ebe8723

    HTTP请求方式:GET

    请求的URI路径(不含HOST):/v3/user/get_info

    请求参数:openid=11111111111111111&openkey=2222222222222222&appid=123456&pf=qzone&format=json&userip=112.90.139.30

  2. 下面开始构造源串:

    第1步:将请求的URI路径进行urlencode编码,得到: %2Fv3%2Fuser%2Fget_info

    第2步:将除“sig”外的所有参数按key进行字典升序排列,排列结果为:appid,format,openid,openkey,pf,userip

    第3步:将第2步中排序后的参数(key=value)用&拼接起来:

    appid=123456&format=json&openid=11111111111111111&openkey=2222222222222222&pf=qzone&userip=112.90.139.30

    然后进行urlencode编码,编码结果为:

    appid%3D123456%26format%3Djson%26openid%3D11111111111111111%26openkey%3D2222222222222222%26pf%3Dqzone%26userip%3D112.90.139.30

    第4步:将HTTP请求方式,第1步以及第3步中的到的字符串用&拼接起来,得到源串:

    GET&%2Fv3%2Fuser%2Fget_info&appid%3D123456%26format%3Djson%26openid%3D11111111111111111%26openkey%3D2222222222222222%26pf%3Dqzone%26userip%3D112.90.139.30

// Demo:

var queryArray = [], params = {
    appid:'',
    openid:'',
    ...
}
for(var key in params){
    if(key != 'sig'){
        queryArray.push(key + '=' + params[key]);
    }
}

queryArray.sort(function (val1, val2) {
    if(val1 > val2){
        return 1;
    }
    if(val1 < val2){
        return -1;
    }
    return 0;
});

var busidataArr = [method, urlencode(pathname), urlencode(queryArray.join('&'))];

var busiDataStr = busidataArr.join('&');

构造密钥

得到密钥的方式:在应用的appkey末尾加上一个字节的“&”,即appkey&,例如:

228bf094169a40a3bd188ba37ebe8723&

生成签名值

  1. 使用HMAC-SHA1加密算法,使用Step2中得到的密钥对Step1中得到的源串加密。

  2. 然后将加密后的结果经过Base64编码转换成字符串。 (注意:先转成字符串再进行base64编码的方法是错误的)

  3. 得到的签名值结果如下:

    FdJkiDYwMj5Aj1UG2RUPc83iokk=

Demo:
var crypto = require('crypto');
var sig = crypto.createHmac('sha1', appkey+'&').update(busiDataStr).digest().toString('base64');

组成OpenApi请求参数

得到签名结果后,即可准备OpenApi请求内容

GET请求示例:

https://api.urlshare.cn/v3/user/get_info?openid=12345&openkey=12345&pf=qzone&appid=1105583577&format=json&userip=10.0.0.1&test=%2A&sig=upLbDHoONj4UEknDSvcun1yEqnk%3D

Demo:
var url = 'https://api.urlshare.cn' + pathname;

if('POST' == method){
    params['sig'] = sig;
    $.POST(url, params, function(result){
        //TODO
    });
}else{
    url+= '?sig=' + sig;
    for(var key in params){
        url+= '&' + encodeURIComponent(key)+ '=' + encodeURIComponent(params[key]);
    }
    $.get(url, function(result){
        //TODO
    });
}