签名算法代码实例

为了帮助理解签名规则,这里提供了部分语言的签名算法实现以供参考。目前支持三种语言:Python、Go和PHP。
入参payload为需要签名的数据字典。请求的json里第一层参数和值的组合。 理论上应该仅包含参与计算的kv,但是程序也做了过滤。

其他参数请根据实际情况替换

Python

import json
import time
import hashlib
import requests


def create_headers(payload):
    """
    创建验签所需信息
    :param payload: 需要签名的数据字典,其中不应包含列表、字典或长于1024个字符的字符串。
    :return:
    """
    sid = 123456
    secret = 'XXXXXX'
    time_stamp = int(time.time())

    # 过滤掉列表、字典或过长的字符串和数值
    filtered_data = {k: v for k, v in payload.items() if not isinstance(v, (list, dict)) and len(str(v)) <= 1024}
    filtered_data['sid'] = sid
    filtered_data['timeStamp'] = time_stamp

    sorted_items = sorted(filtered_data.items())  # 将字典项排序
    sign_string = "&".join(f"{key}={value}" for key, value in sorted_items)   # 构建用于签名的字符串

    # 拼接签名密钥
    sign_string += "&key={}".format(secret)
    sign = hashlib.md5(sign_string.encode('utf-8')).hexdigest()

    headers = {
        'X-EEO-SIGN': sign,
        'X-EEO-UID': f'{sid}',
        'X-EEO-TS': f'{time_stamp}',
        'Content-Type': 'application/json'
    }
    print(f'headers: {headers}')
    return headers

Go

import (
    "crypto/md5"
    "encoding/hex"
    "fmt"
    "sort"
    "strconv"
    "strings"
    "time"
)

func createHeaders(payload map[string]interface{}) map[string]string {
    sid := 123456
    secret := "XXXXXX"
    timeStamp := strconv.FormatInt(time.Now().Unix(), 10)

    // 过滤掉列表、字典或过长的字符串和数值
    var filteredData []string
    for k, v := range payload {
        switch v.(type) {
        case []interface{}, map[string]interface{}, string:
            if str, ok := v.(string); ok && len(str) <= 1024 {
                filteredData = append(filteredData, fmt.Sprintf("%s=%v", k, v))
            }
        default:
            if num, ok := v.(int); ok {
                filteredData = append(filteredData, fmt.Sprintf("%s=%d", k, num))
            }
        }
    }

    // 添加 sid 和 timeStamp
    filteredData = append(filteredData, "sid="+strconv.Itoa(sid))
    filteredData = append(filteredData, "timeStamp="+timeStamp)

    // 将字典项排序
    sort.Strings(filteredData)

    // 构建用于签名的字符串
    signString := strings.Join(filteredData, "&")
    signString += "&key=" + secret
    fmt.Printf("signString: %s\n", signString)
    // 使用MD5算法生成签名
    hash := md5.Sum([]byte(signString))
    sign := hex.EncodeToString(hash[:])

    headers := map[string]string{
        "X-EEO-SIGN":   sign,
        "X-EEO-UID":    strconv.Itoa(sid),
        "X-EEO-TS":     timeStamp,
        "Content-Type": "application/json",
    }

    return headers
}

PHP

<?php
function sign($body=[]){
    $eeoUId = $body['sid'];
    $secret = $body['secret'];
    $eeoTs = time();
    if(isset($body['secret'])){
        unset($body['secret']);
    }
    foreach($body as $key => $value){
        if(!is_array($value) && strlen($value) < 1024){
            $signParams[$key] = $value;
        }
    }
    $signParams['timeStamp'] = $eeoTs;
    ksort($signParams);
    $signString = '';
    foreach ($signParams as $key=>$value) {
        $signString .= $key . '=' . $value . '&';
    }
    $signString .= "key=".$secret;
    $sign = md5($signString);
    if(isset($body['sid'])){
        unset($body['sid']);
    }
    $headers = [
        'X-EEO-SIGN:'   .   $sign,
        'X-EEO-UID:'    .   $eeoUId,
        'X-EEO-TS:'     .   $eeoTs,
        'Content-Type:application/json'
    ];
    return $body = [
        'headers'    => $headers,
        'body'       => json_encode($body),
    ];
}

function curlPost($url,$params=[],$headers=[]){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS,$params);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POST,1);
    $result = curl_exec($ch);
    curl_close($ch);
    return json_decode($result, true);
}

//创建课堂示例
function createClass(){
    $url    = 'https://api.eeo.cn/lms/activity/createClass';
    $body   = [
        'sid'       =>  xxx, // SID
        'secret'    =>  'xxx', // SECRET
        'courseId'  =>  xxx,   // 课程ID
        'unitId'    =>  xxx,   // 单元ID
        'name'      =>  '课节名称', // 编辑单元50字,客户端100字
        'teacherUid'    =>  "老师UID",
        'startTime'     =>  开课时间,
        'endTime'       =>  结束时间
    ];
    $signParams = sign($body);
    $result = curlPost($url, $signParams['body'], $signParams['headers']);
    return $result;
}
createClass();

?>

results matching ""

    No results matching ""