微店商品详情 API 签名机制实现:轻量加密逻辑与多语言适配
签名机制核心逻辑
微店 API 签名采用 MD5/HMAC-SHA256 加密 + 参数排序拼接 机制,确保请求合法性和数据安全性。核心步骤如下:
参数准备
必传参数:
app_key(应用密钥)、access_token(授权令牌)、timestamp(时间戳,防止重放攻击)、item_id(商品 ID)可选参数:
format(返回格式,默认 JSON)、v(API 版本)参数排序与拼接
按参数名 ASCII 升序排序(如
access_token→app_key→item_id→timestamp)拼接为
key=value&key=value...格式,示例:access_token=xxxx&app_key=123456&item_id=67890×tamp=1726000000
添加密钥并加密
在拼接字符串 首尾添加 App Secret,形成:
AppSecret + 拼接字符串 + AppSecret使用 MD5 或 HMAC-SHA256 加密,结果转换为 大写,示例(MD5):
pythonimport hashlibdef generate_sign(params, app_secret): sorted_params = sorted(params.items()) param_str = ''.join([f'{k}{v}' for k, v in sorted_params]) sign_str = f"{app_secret}{param_str}{app_secret}" return hashlib.md5(sign_str.encode()).hexdigest().upper()发送请求
将签名作为
sign参数添加到请求中,通过 HTTP GET/POST 发送。
多语言适配示例
以下提供 Python、Java、JavaScript 三种语言的实现代码:
Python 示例
pythonimport requestsimport hashlibimport timeAPP_KEY = "your_app_key"APP_SECRET = "your_app_secret"ACCESS_TOKEN = "your_access_token"ITEM_ID = "123456"def generate_sign(params, secret): sorted_params = sorted(params.items()) param_str = ''.join([f'{k}{v}' for k, v in sorted_params]) sign_str = f"{secret}{param_str}{secret}" return hashlib.md5(sign_str.encode()).hexdigest().upper()params = { "app_key": APP_KEY, "access_token": ACCESS_TOKEN, "item_id": ITEM_ID, "timestamp": str(int(time.time()))}params["sign"] = generate_sign(params, APP_SECRET)response = requests.get("https://api.weidian.com/item/get", params=params)print(response.json())Java 示例
javaimport javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;import java.net.URLEncoder;import java.util.*;public class WeidianSign { public static String generateSign(Map<String, String> params, String secret) throws Exception { // 参数排序 List<String> keys = new ArrayList<>(params.keySet()); Collections.sort(keys); StringBuilder sb = new StringBuilder(); for (String key : keys) { sb.append(key).append(params.get(key)); } String signStr = secret + sb.toString() + secret; // HMAC-SHA256 加密 Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(secret.getBytes(), "HmacSHA256")); byte[] bytes = mac.doFinal(signStr.getBytes()); StringBuilder sign = new StringBuilder(); for (byte b : bytes) { sign.append(String.format("%02x", b)); } return sign.toString().toUpperCase(); } public static void main(String[] args) throws Exception { Map<String, String> params = new HashMap<>(); params.put("app_key", "your_app_key"); params.put("access_token", "your_access_token"); params.put("item_id", "123456"); params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000)); String sign = generateSign(params, "your_app_secret"); params.put("sign", sign); // 发送请求(示例使用 OkHttp) // OkHttpClient client = new OkHttpClient(); // Request request = new Request.Builder().url("https://api.weidian.com/item/get?" + buildQueryString(params)).build(); }}JavaScript 示例(Node.js)
javascriptconst axios = require('axios');const crypto = require('crypto');const APP_KEY = 'your_app_key';const APP_SECRET = 'your_app_secret';const ACCESS_TOKEN = 'your_access_token';const ITEM_ID = '123456';function generateSign(params, secret) { const sortedKeys = Object.keys(params).sort(); const paramStr = sortedKeys.map(key => `${key}${params[key]}`).join(''); const signStr = `${secret}${paramStr}${secret}`; return crypto.createHash('md5').update(signStr).digest('hex').toUpperCase();}const params = { app_key: APP_KEY, access_token: ACCESS_TOKEN, item_id: ITEM_ID, timestamp: Math.floor(Date.now() / 1000)};params.sign = generateSign(params, APP_SECRET);axios.get('https://api.weidian.com/item/get', { params }) .then(response => console.log(response.data)) .catch(error => console.error(error));关键注意事项
安全性
App Secret 保护:禁止前端暴露,通过后端代理调用 API。
HTTPS 传输:所有请求使用 HTTPS,防止中间人攻击。
签名验证:服务端需验证签名,确保请求未被篡改。
错误处理
签名错误:检查参数排序、拼接规则及加密算法是否正确。
频率限制:默认 QPS ≤ 50,超限返回 429 错误,采用指数退避重试。
Token 过期:
access_token有效期 2 小时,需定期刷新。多语言适配要点
参数排序:确保所有语言实现一致的 ASCII 升序排序。
字符串拼接:避免额外字符(如空格)干扰签名。
加密算法:MD5/HMAC-SHA256 需在各语言中正确实现,结果转大写。
通过上述机制,可实现微店商品详情 API 的安全调用,适配多语言开发需求,保障数据传输的完整性与安全性。