热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

抖音小程序实践三:接口开发指南

通过官方文档可以更系统的学习到所有的接口,我这边罗列一下我自己用到测试过的接口供大家参考。前端-小程序对接官方文档:https:microapp.by


通过官方文档可以更系统的学习到所有的接口,我这边罗列一下我自己用到测试过的接口供大家参考。


  1. 前端-小程序对接官方文档:https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/api/open-interface/user-information/tt-get-user-info
  2. 服务端-小程序官方文档:https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/server/server-api-introduction

在这里插入图片描述


1.前端-获取用户信息授权

API文档:https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/api/open-interface/user-information/tt-get-user-info

// tt.getUserProfile(); 获取用户的基本信息,只可在 tap和支付 事件回调中调用,每次调用都会弹出授权提示窗,若用户同意,则会返回用户的真实数据。
//获取已登录用户的基本信息或特殊信息,首次使用的用户会弹出授权提示窗,若用户同意,则会返回用户的真实数据。
tt.getUserInfo({
success(res) {
console.log("getUserInfo 调用成功", JSON.stringify(res));
},
fail(res) {
console.log("getUserInfo 调用失败", JSON.stringify(res));
},
})

响应:

{
"userInfo": {
"nickName": "claxxxxxhen",
"avatarUrl": "https://p9-passport.byteacctimg.com/img/mosaic-legacy/3796/2975xxx00.image",
"gender": 0,
"city": "",
"province": "",
"country": "",
"language": "",
"userId": "37431xxxxx1486",
"sessionId": "3b652xxxxxxc3b490351ef1311"
},
"rawData": "{\"nickName\":\"claixxxxn\",\"avatarUrl\":\"https://p9-passport.byteacctimg.com/img/mosaic-legacy/3796/297xxxx.image\",\"gender\":0,\"city\":\"\",\"province\":\"\",\"country\":\"\",\"language\":\"\"}",
"signature": "5fed6c636f3cdxxxxx3d2e97e0869d0",
"encryptedData": "G+kEtB+JE2S3/r8V0Ftxxxx/CxxxxxxxxxxxxxFKKLp6LNpm3QtoHlj2BZREiN8zSE8z7gK51ECsKFDyPn4mtuthY90zj+Zwx0EPyC+DwP1ZJ4ahVawzVkMdnBMhnT48+7CZvOAWa/LyY93MmSsDNLDR0BBTpBnYbnqSW3tGNvTcllNuX2F1Laso2RtsFQlQPoVvoBysfIxliFDvL2+Rw/ZEIc2i7uXnbDeTzPuiiC8km7a/ImZSEZiTdsGNDKEnepmYStswydENgG51NiPRwj15JyOAeALb34xhgYFFZGZFw703XGUbXIn8s8tbqJ+u72cjbqxTp/D7qBL2cHA3uJC6rhrM/VgH7hiDMlwApdRQuFcNQSItQ41RhcD14R7iFoQObc4/IPT0BmvG+WuKMV+PuEp8vaA==",
"iv": "ar8P0OkTQxxxxqHrW9w==",
"errMsg": "getUserProfile:ok"
}

  • 其中encryptedData是需要的用户openId等数据
  • iv是用于解密的,需要留存

Q:此外,什么是用户的openId?什么是用户的unionId?
A:开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性。也就是说,小程序内openId是唯一的,全平台unionId是唯一的。


2.前端-用户登录

API文档:https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/develop/api/open-interface/log-in/tt-login

tt.login({
force: true,
success(res) {
console.log(`login 调用成功${res.code} ${res.anonymousCode}`);
},
fail(res) {
console.log(`login 调用失败`);
},
});

响应:

{
"anonymousCode": "UAx9YfgVDsxxxxxxxxxxiZCXh7OaAfiW8ei…6mhQP1ETXRfFRKxidnPqMxZtxgXv7yrbWjkBwVePN6FIJq-1Q",
"code": "1ujmWYVW0mlU4xzzzzzzxxxxxxxxMUkdf9Vp1…g9z0Gy8LFbNekfVjY-Ng6V4_Bc6HxAPQ-SQvrPS8Gf-1ZFvaE",
"isLogin": true,
"errMsg": "login:ok"
}

tt.login调用douyin接口登录,获取code/anonymous_code,这两个字段是后续个人加密信息解密的重要字段


3.服务端-jscode2session换取sessionKey

API文档:https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/server/log-in/code-2-session/

Map<String, String> dataMap &#61; new HashMap<>();
dataMap.put("appid", "tt60d416xxxxc8801");
dataMap.put("secret", "582830exxxxc99e14c0999a");
dataMap.put("code", "3muFdjQoIFZw0WcBLhltspBxxxxxNfT6mkCQO4RbKicdR0j7a12-PRO6yRCHn90HYDg8DerKt_lxoVr1Donbw");
dataMap.put("anonymous_code", "i8MsKM6tGuKzjxMH3vJF3R4NxAN6xxxxxxxx38wsHAcfmY4dXwaWInvy6isFJ5X8ejQzKcYJVgiPCPkBkMwkw4MrRjFY_iVDOcTOY74");
HttpResult httpResult &#61; HttpClientUtils.doPostJson("https://developer.toutiao.com/api/apps/v2/jscode2session", JSON.toJSONString(dataMap));//注意这是生产的地址
String res &#61; httpResult.getBody();
System.out.println(res);

响应&#xff1a;

{
"err_no": 0,
"err_tips": "success",
"data": {
"session_key": "hZy6t19VPjFqm********",
"openid": "V3WvSshYq9******",
"anonymous_openid": "",
"unionid": "f7510d9ab***********"
}
}

  • 这个时候能够获取session_key&#xff08;解密用户信息的重点字段&#xff09;&#xff0c;此外还有重要的用户openid和unionid

4.服务端-敏感信息解密

API文档&#xff1a;https://microapp.bytedance.com/docs/zh-CN/mini-app/develop/api/open-interface/user-information/sensitive-data-process/
这边测试解密用户信息&#xff0c;此外手机号等encryptData的数据&#xff0c;都可以拿这套流程来解密。
我这边主要写了java后端解密的方法&#xff0c;对于js也可以解密&#xff0c;官方文档有比较多的方法展示。

Base64.Decoder decoder &#61; Base64.getDecoder();
byte[] sessionKeyBytes &#61; decoder.decode("Ps2xsxxxxxxxJkA&#61;&#61;");
byte[] ivBytes &#61; decoder.decode("ar8P0OxxxxxxqHrW9w&#61;&#61;");
byte[] encryptedBytes &#61; decoder.decode("cfOy32OwcBaZv7xxxxxxxxxxxvZQHOjzDABhBOWInm0PNGwzXIBkUIZmto2pjC8VDmZS3v3N27OCb2c5E7DblfSVbcjXHuZN7OPB&#43;zOxDADD7Q&#61;&#61;");
Cipher cipher &#61; Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec skeySpec &#61; new SecretKeySpec(sessionKeyBytes, "AES");
IvParameterSpec ivSpec &#61; new IvParameterSpec(ivBytes);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
byte[] ret &#61; cipher.doFinal(encryptedBytes);
String res &#61; new String(ret);
System.out.println(res);

  • 注意&#xff1a;Cipher cipher &#61; Cipher.getInstance(“AES/CBC/PKCS5Padding”); // JDK does not support PKCS7Padding, use PKCS5Padding instead
  • 以上会有一个坑&#xff0c;对于JDK版本的不同&#xff0c;对解密的key的长度会有限制。比如Illegal key size or default parameters这种错误。因为美国的出口限制&#xff0c;Sun通过权限文件&#xff08;local_policy.jar、US_export_policy.jar&#xff09;做了相应限制。因此存在一些问题&#xff1a;●密钥长度上不能满足需求&#xff08;如&#xff1a;java.security.InvalidKeyException: Illegal key size or default parameters&#xff09;&#xff0c;然后网上说要通过替换JDK/jre/lib/security的local_policy.jar
  • 我们正好遇到了服务器上的JDK版本较老&#xff0c;本地的JDK比较新&#xff0c;而上线报错这样的问题&#xff0c;下面的方法亲测解决异常
  • 关于JDK如何启用无限强度加密&#xff1a;
    • 针对Java 8u151之前版本&#xff0c;内含有限强度策略文件&#xff0c;我们下载 oracle上的无限制版本替换local_policy.jar、US_export_policy.jar
    • 针对Java 8u151之后版本&#xff0c;默认采用无限强度策略文件&#xff0c;如果我们想定义要使用的版本&#xff0c;有一个安全属性crypto.policy。Security.setProperty(“crypto.policy”,“unlimited”).在JCE框架初始化之前设置该属性。

5.再看看敏感数据解密流程


  1. tt.login调用douyin接口登录&#xff0c;获取code/anonymous_code
  2. getUserProfile&#xff0c;获取iv、encryptedData
  3. jscode2session 获取session_key &#xff08;前后端获取均可&#xff09;
  4. 解密用户信息 &#xff08;前后端解密均可&#xff09;&#xff0c;注意保存用户信息

这样就能够获取openid\unionid\用户明文信息了


6.前端-获取用户设备信息

tt.getSystemInfo({
success(res) {
console.log("getSystemInfo 调用成功", JSON.stringify(res));
},
fail(res) {
console.log("getSystemInfo 调用失败", JSON.stringify(res));
},
});

响应&#xff1a;


"language": "zh_CN",
"version": "6.6.3",
"brand": "devtools",
"fontSizeSetting": 16,
"platform": "devtools",
"battery": 100,
"wifiSignal": 4,
"appName": "devtools",
"statusBarHeight": 47,
"nativeSDKVersion": "10.3.0",
"model": "iPhone 12",
"system": "iOS 14",
"deviceScore": {
"cpu": 7.905,
"gpu": 9.0622,
"memory": 7.0344,
"overall": 7.9524
},
"SDKVersion": "2.68.0",
"pixelRatio": 3,
"screenWidth": 390,
"screenHeight": 844,
"windowWidth": 390,
"windowHeight": 844,
"safeArea": {
"left": 0,
"right": 390,
"top": 47,
"bottom": 810,
"width": 390,
"height": 763
},
"SDKUpdateVersion": "2.68.0.3",
"devicePixelRatio": 3,
"errMsg": "getSystemInfo:ok"
}

7.前端-获取用户手机号

获取抖音API当前登录状态的手机号&#xff0c;获取前需用户授权&#xff0c;否则无法获取。注意&#xff1a;该能力无法直接使用&#xff0c;需申请白名单

小程序获取手机号授权能力仅适用于以下场景&#xff1a;网络购物、帐号下信息内容同步、票务预订、业务办理、信息查询&#xff08;如&#xff1a;社保、公积金&#xff09;、预约等&#xff0c;其他不符合使用规范的申请不予开通&#xff0c;申请可参考&#xff1a; 获取用户手机号开通指南

评级达 B 级&#xff0c;且信用分达到 90 分的企业主体小程序&#xff0c;可以申请获取用户手机号能力

tt.getPhoneNumber({
success(res) {
console.log("getPhoneNumber 调用成功", JSON.stringify(res));
},
fail(res) {
console.log("getPhoneNumber 调用失败", JSON.stringify(res));
},
})

响应&#xff1a;

{
"detail": {
"cloudId": "",
"encryptedData": "0tJ8EV5kwMq8xxxxxxQmf1KG2yKVJX3pYMgWbnY4SJ0MmWMFHJx1ySIaWIgt09sMCL0vAPmgMQ8Hv6d9NgRksOYDTdO1JEmJMy4VGJpBUKL3qqcOvBIc6ToN3RyUTad6Q&#61;&#61;",
"iv": "ZtZtYvS7gNbGMpyYg500rA&#61;&#61;",
"errMsg": "getPhoneNumber:ok"
},
"errMsg": "getPhoneNumber:ok"
}

这个数据就一样解密即可


8.前端-获取用户精准位置信息

用于频繁请求地理位置&#xff0c;实时获取精确位置信息。一般适用于打车、外卖等需要频繁请求获取地理位置的行业。需要申请后可查看。

tt.chooseAddress({
success(res) {
console.log("chooseAddress 调用成功", JSON.stringify(res));
},
fail(res) {
console.log("chooseAddress 调用失败", JSON.stringify(res));
},
})

只要有接口权限&#xff0c;并且是用户登录授权状态&#xff0c;即可获取
响应&#xff1a;

{
"longitude": 116.3974,
"latitude": 39.9092,
"city": "北京市",
"speed": 0,
"accuracy": 65,
"altitude": 0,
"verticalAccuracy": 65,
"horizontalAccuracy": 65,
"errMsg": "getLocation:ok"
}

9.前端-消息订阅

前端发起用户订阅订单消息通知&#xff0c;用户同意后&#xff0c;即可通过接口发送实时订单消息给用户&#xff0c;提升用户体验

小程序消息订阅能力说明

注意&#xff1a;沙盒内测试仅支持安卓&#xff0c;如绑定的设备是IOS的测试会报错 — {"errMsg":"requestSubscribeMessage:fail not supported by current application","errNo":21502}

tt.requestSubscribeMessage({
tmplIds: [], // 需要填入开放平台申请的模版id&#xff0c;支持最多3个同类型模版
success(res) {
//订阅成功
console.log("订阅成功", res);
},
fail(error) {
//订阅失败
console.log("订阅失败, 错误详情: ", error);
tt.showToast({
title: "订阅失败",
icon: "fail",
});
},
complete(res) {
//订阅完成
console.log("tt.requestSubscribeMessage API调用完成: ", res);
},
});

如果是安卓设备&#xff0c;请求结果如下&#xff1a;

{
"MSG137673105551c58exxxxx15858": "accept",
"itemSettings": {
"MSG137673105551cxxxxxbf15858": "accept"
},
"errMsg": "requestSubscribeMessage:ok"
}

10.服务端-获取AccessToken

AccessToken是接口鉴权凭证
access_token 是小程序的全局唯一调用凭据&#xff0c;开发者调用小程序支付时需要使用 access_token。access_token 的有效期为 2 个小时&#xff0c;需要定时刷新 access_token&#xff0c;重复获取会导致之前一次获取的 access_token 的有效期缩短为 5 分钟。

接口&#xff1a;POST https://developer.toutiao.com/api/apps/v2/token
请求示例:

curl --location --request POST &#39;https://developer.toutiao.com/api/apps/v2/token&#39; \
--header &#39;Content-Type: application/json&#39; \
--data-raw &#39;{
"appid": "ttabc*****",
"secret": "d428***********",
"grant_type": "client_credential"
}&#39;

响应&#xff1a;

{
"err_no": 0,
"err_tips": "success",
"data": {
"access_token": "0801121***********",
"expires_in": 7200
}
}

11.服务端-发送订阅消息

请求地址&#xff1a; POST https://developer.toutiao.com/api/apps/subscribe_notification/developer/v1/notify
POSTMAN中的请求示例

curl --location --request POST &#39;https://developer.toutiao.com/api/apps/subscribe_notification/developer/v1/notify&#39; \
--header &#39;Content-Type: application/json&#39; \
--data-raw &#39;{
"access_token": "080112184679zzzz7556f426d33673d3d",
"app_id": "tt60d4166zzzzzzz8801",
"tpl_id": "MSG137673105zzzzzz7c84bf15858",
"open_id": "_000S3uzzzzzzzzAzN_zZb",
"data": {
"快递派送": "SF1111111111"
}
}&#39;

响应&#xff1a;

{
"err_no": 0,
"err_tips": ""
}






推荐阅读
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • Android Studio Bumblebee | 2021.1.1(大黄蜂版本使用介绍)
    本文介绍了Android Studio Bumblebee | 2021.1.1(大黄蜂版本)的使用方法和相关知识,包括Gradle的介绍、设备管理器的配置、无线调试、新版本问题等内容。同时还提供了更新版本的下载地址和启动页面截图。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
author-avatar
Mr_cool
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有