淘宝上取SessionKey 淘宝网开放平台API(taobao.user.get)调用示例,需SessionKey

本文介紹了一個使用C#處理淘寶API請求的示例代碼,展示了如何通過HTTP請求與淘寶平臺交互並獲取用戶數據。該代碼包括應用級和系統級參數設置、簽名生成、URL構造及結果解析等關鍵步驟。
程序代码
<%@ WebHandler Language="C#" Class="TOP" %>
using System;
using System.Web;
using System.Net;
using System.Xml;
using System.Text;
using System.Web.Security;
using System.Collections.Generic;
public class TOP : IHttpHandler {
    
    public void ProcessRequest (HttpContext context) {
        //1.应用信息
        string app_key = "10011201";
        string app_secret = "0fd3ffcb7008570b95670ec5ad3fe201";
        //2.参数集
        SortedList<string, string> parameters = new SortedList<string, string>();
        //2.1 应用级输入参数
        parameters.Add("fields", "user_id,nick,sex,location.city,birthday,type,has_more_pic");//后3个为隐私数据
        parameters.Add("nick", "alipublic01");
        //2.2 系统级参数
        parameters.Add("method", "taobao.user.get");
        parameters.Add("session", context.Request.QueryString["top_session"] == null ? "" : context.Request.QueryString["top_session"].ToString());
        parameters.Add("timestamp", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
        parameters.Add("format", "xml");
        parameters.Add("app_key", app_key);
        parameters.Add("v", "1.0");
        //2.3 生成sign,格式: app_secret参数1值1参数2值2,生成md5后转为大写
        StringBuilder sb = new StringBuilder();
        sb.Append(app_secret);
        foreach (KeyValuePair<string, string> item in parameters)
        {
            sb.Append(item.Key + item.Value);
        }
        parameters.Add("sign", FormsAuthentication.HashPasswordForStoringInConfigFile(sb.ToString(), "MD5").ToUpper());
        //3.生成url
        string url = "http://gw.sandbox.taobao.com/router/rest?";//线上环境: http://gw.api.taobao.com/router/rest  测试环境: http://gw.sandbox.taobao.com/router/rest
        StringBuilder query = new StringBuilder();
        foreach (KeyValuePair<string, string> item in parameters)
        {
            query.Append(item.Key + "=" + System.Web.HttpUtility.UrlEncode(item.Value, System.Text.Encoding.UTF8) + "&");
        }
        url += query.ToString().TrimEnd(new char[] { '&' });
        //4.淘宝客商品查询
        try
        {
            WebRequest webRequest = WebRequest.Create(new Uri(url));
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.Method = "POST";
            webRequest.Timeout = 5000;
            XmlDocument xmlDocument = new XmlDocument();
            xmlDocument.Load(((WebResponse)webRequest.GetResponse()).GetResponseStream());
            context.Response.ContentType = "text/xml";
            context.Response.Write(xmlDocument.InnerXml);
        }
        catch (Exception ex)
        {
            context.Response.Write(ex.Message);
        }
    }
    public bool IsReusable {
        get {
            return false;
        }
    }
}
测试流程
1.测试环境下测试
1).保存上边代码到top.ashx,并上传至http://www.mzwu.com/top.ashx;
2).打开http://open.taobao.com/isv/authorize.php?appkey=10011201;
3).选择测试帐号alipublic01, 回调URL为http://www.mzwu.com/top.ashx,点击获取授权码,形如:PpAE1wquKJoxTtYyJUszOTTfIK5NTpxPpZ%2BH%2BrbJBGS63dDaKbihaSvn9k8QSZQ%2BLIuurtyuKV%2B1jz5JLLeUHblN3LqzbBf%2B%2BTXb6y4OEe4pF9BuV%2ByqS68g%2F7HCkhkwArNCYPNW%2BD5Wbqx2y0Ey1pFuL1t1zsrk8BEw4hbM6XAhgtSgwKfvGQ%3D%3D;
4).打开http://container.sandbox.taobao.com/container?authcode={上一步的授权码},将跳转到回调URL中,如:http://www.mzwu.com/top.ashx?top_appkey=12001690&top_parameters=aWZyYW1lPTEmdHM9MTI0NjUzNzg5NDk2MiZ2aWV3X21vZGU9ZnVsbCZ2aWV3X3dpZHRoPTAmdmlzaXRvcl9pZD0xNzU3NTQzNTEmdmlzaXRvcl9uaWNrPWFsaXB1YmxpYzAx&top_session=1a059e31dd95ad9968674fb77940e037c&top_sign=1d065Wmf1iO08sRFhTPbAw%3D%3D,其中top_session即为SessionKey;
5).调用 taobao.user.get API即可查看alipublic01敏感信息;
2.正式环境下测试
1).修改上边代码nick和url保存为top.ashx,并上传至http://www.mzwu.com/top.ashx;
2).将应用升到正式环境,保存回调地址为http://www.mzwu.com/top.ashx;
3).打开http://auth.open.taobao.com/?appkey=10011201(若未登录将跳转到登录页后再跳转回来),同意申明后页面即显示授权码,形如:TOP-10bc0a8761e98193145846b9fdbada777cyc3dNl5kFr0Rnz8aEmr7wxvQBa9G5r-END;
4).打开http://container.open.taobao.com/container?authcode={上一步授权码},将跳转到回调URL中,如:http://www.mzwu.com/top.ashx?top_appkey=12001690&top_parameters=aWZyYW1lPTEmdHM9MTI0NjUzODE3NzI3OSZ2aWV3X21vZGU9ZnVsbCZ2aWV3X3dpZHRoPTAmdmlzaXRvcl9pZD0yMDA4NTYyMjYmdmlzaXRvcl9uaWNrPcLM0ray6M%2Fj&top_session=1ea4749bf3159c702a91cd694319b8e4a&top_sign=qJZoEflAVx5Muzl98VHyjg%3D%3D,其中top_session即为SessionKey;
5).调用 taobao.user.get API即可查看登录用户的敏感信息;
`wx.getPhoneNumber(Object object)` 是微信小程序中用于获用户手机号的 API,但它的使用有严格限制和特定流程。下面我会 **详尽地讲解如何正确调用和使用它**,包括前端代码、后端解密逻辑,并解释注意事项。 --- ## ✅ 一、`wx.getPhoneNumber` 的作用 > 通过用户点击按钮触发,获用户的加密手机号信息(`encryptedData` 和 `iv`),然后在**后端配合 `session_key` 解密**得到明文手机号。 ⚠️ 注意:这个 API **不能直接返回明文手机号**,必须配合服务端解密。 --- ## 🔐 二、权限与前提条件 | 条件 | 是否必 | |------|----------| | 用户已登录(调用过 `wx.login()`) | ✅ 必须 | | 小程序已上线或体验版 | ✅ 必须(开发版无法获真实数据) | | 用户主动点击按钮授权 | ✅ 必须 | | 小程序类目符合要求(如非个人主体) | ✅ 部分类目受限 | > ❗ 个人类型小程序无法使用 `getPhoneNumber` 接口! --- ## 🧩 三、完整使用流程 ```text 1. 用户进入页面 ↓ 2. 点击 <button open-type="getPhoneNumber"> ↓ 3. 前端收到 encryptedData + iv ↓ 4. 发送给后端 ↓ 5. 后端用 session_key 解密 → 得到手机号 ``` --- ## 💻 四、前端调用方式(WXML + JS) ### 1. WXML 模板:使用 `open-type="getPhoneNumber"` ```html <!-- wxml --> <button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber"> 获手机号 </button> ``` ### 2. JavaScript 处理回调 ```js Page({ data: { userInfo: null }, // 获手机号事件 getPhoneNumber(e) { console.log('getPhoneNumber event:', e); if (e.detail.errMsg === 'getPhoneNumber:ok') { const { encryptedData, iv } = e.detail; // 发送到开发者服务器进行解密 wx.request({ url: 'https://yourdomain.com/api/decrypt-phone', method: 'POST', header: { 'content-type': 'application/json' }, data: { encryptedData, iv, // 注意:不要传 session_key!应由后端根据 code 自行获 }, success: (res) => { if (res.data.success) { console.log('用户手机号为:', res.data.phoneNumber); } else { console.error('解密失败:', res.data.message); } }, fail: (err) => { console.error('请求失败:', err); } }); } else if (e.detail.errMsg === 'getPhoneNumber:fail user deny') { wx.showToast({ title: '您拒绝了授权', icon: 'none' }); } else { wx.showToast({ title: '获失败', icon: 'none' }); } } }); ``` --- ## ⚙️ 五、后端解密手机号(Node.js 示例) 你要先通过 `wx.login()` 获 `code`,并用 `code` 换 `session_key`。 ### 步骤 1:前端登录获 code ```js wx.login({ success(res) { if (res.code) { wx.request({ url: 'https://yourdomain.com/api/wx/login', method: 'POST', data: { code: res.code } }); } } }); ``` ### 步骤 2:后端用 `code` 换 `session_key`(Node.js) ```js // routes/wx.js const axios = require('axios'); // 微信接口地址 const WX_LOGIN_URL = 'https://api.weixin.qq.com/sns/jscode2session'; exports.login = async (req, res) => { const { code } = req.body; const appId = '你的AppID'; const secret = '你的AppSecret'; try { const response = await axios.get(WX_LOGIN_URL, { params: { appid: appId, secret: secret, js_code: code, grant_type: 'authorization_code' } }); const { openid, session_key, unionid } = response.data; // 存入缓存(如 Redis),key 可以是 token 或 sessionId const token = generateToken(); // 自定义生成 cache.set(token, { openid, session_key }, 60 * 60); // 缓存1小时 res.json({ token, openid }); } catch (error) { res.status(500).json({ error: '登录失败' }); } }; ``` ### 步骤 3:解密手机号(Node.js 使用 crypto) ```js const crypto = require('crypto'); function decryptPhoneNumber(encryptedData, iv, sessionKey) { try { const sessionKeyBuffer = Buffer.from(sessionKey, 'base64'); const encryptedDataBuffer = Buffer.from(encryptedData, 'base64'); const ivBuffer = Buffer.from(iv, 'base64'); const decipher = crypto.createDecipheriv('aes-128-cbc', sessionKeyBuffer, ivBuffer); decipher.setAutoPadding(true); let decoded = decipher.update(encryptedDataBuffer, null, 'utf8'); decoded += decipher.final('utf8'); const result = JSON.parse(decoded); return result.phoneNumber ? result : null; } catch (err) { console.error('解密失败:', err); return null; } } // 接收前端 POST 请求 exports.decryptPhone = (req, res) => { const { encryptedData, iv } = req.body; const token = req.header('Authorization'); // 或从 cookie/session const cached = cache.get(token); // 获之前存储的 session_key if (!cached) { return res.json({ success: false, message: '登录已过期' }); } const { session_key } = cached; const phoneData = decryptPhoneNumber(encryptedData, iv, session_key); if (phoneData) { res.json({ success: true, phoneNumber: phoneData.phoneNumber }); } else { res.json({ success: false, message: '解密失败,请检查参数' }); } }; ``` --- ## 📦 六、返回结果说明 ### 前端 `e.detail` 结构: ```js { errMsg: "getPhoneNumber:ok", encryptedData: "xxx", // 加密字符串 iv: "yyy" // 初始向量 } ``` ### 后端解密成功后得到的数据示例: ```json { "phoneNumber": "13800138000", "purePhoneNumber": "13800138000", "countryCode": 86, "watermark": { "appid": "wx1234567890abcdef", "timestamp": 1712345678 } } ``` --- ## ❗ 七、常见错误与解决方案 | 错误 | 原因 | 解决方法 | |------|------|---------| | `user deny` | 用户拒绝授权 | 提示用户重新点击 | | `invalid code` | code 过期或无效 | 重新调用 `wx.login()` | | `illegal buffer` | 解密失败(iv 或 session_key 错误) | 检查 base64 解码是否正确 | | 开发者工具显示模拟数据 | 不是真实手机号 | 必须真机测试且发布体验版 | --- ## ✅ 八、最佳实践建议 1. **不要在前端尝试解密**:`session_key` 绝对不能暴露; 2. **使用 token 管理会话**:将 `session_key` 存在服务端,绑定用户 session; 3. **做好异常处理**:用户可能消授权; 4. **真机调试**:开发工具里的手机号是虚拟的,只有真机+体验版才能拿到真实号码; 5. **合规使用**:仅用于用户同意的场景(如注册、下单等),遵守《微信隐私保护指引》。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值