【原创 附源码】Flutter海外登录--Tiktok登录最详细流程

news2025/1/22 13:03:31

最近接触了几个海外登录的平台,踩了很多坑,也总结了很多东西,决定记录下来给路过的兄弟坐个参考,也留着以后留着回顾。更新时间为2024年2月7日,后续集成方式可能会有变动,所以目前的集成流程仅供参考,但是绝对详细。

整个记录会包含源码。

dart环境:sdk: '>=2.7.0 <3.0.0'

集成海外登录需要科学上网,一共涉及四个平台,Tiktok,Facebook,Google以及Apple登录。我会分别一一整理记录,所以我的项目就命名为fgta_login (Facebook,Google,Tiktok,Apple登录),奇怪的命名+1。

这篇文章只记录TikTok登录的详细流程,其他几个平台的登录会陆续更新,

一 TikTok开发者官网配置

首先去TikTok开发者官网去注册账号,并创建一个app,登记上安卓和iOS端的信息

TikTok开发者官网地址:https://developers.tiktok.com/

进来后点击用户头像,然后点击【应用管理】

然后点击创建app

输入创建的项目名

然后根据你的app,配置完所有信息,app图标、说明、隐私协议之类的。

打开安卓和iOS平台的配置,按需选择,做哪个平台启用哪个平台就好了

开始安卓端配配置,需要如下几个参数:

Android package name:在安卓项目这里找

Google Play Store URL:谷歌商店链接,这个需要你的安卓端在谷歌商店审核通过之后才会有,如果审核不通过的话,Tiktok这里创建的app提交之后也是不通过的。建议谷歌商店审核通过之后再来做安卓端的Tiktok集成。

App signature 应用签名:告诉大家一个快捷的获取方法,使用android studio提供的gradle插件,点击如下两个地方,切记粘贴到Tiktok上的时候,要去掉中间链接的【:】号,不然会报错

Signing certificate fingerprints 证书指纹:也在同样的地方获取,这个不需要去除中间的冒号

安卓端的配置就完成了,最后配置结果如下

开始iOS端配配置:

App Store URL :苹果商店的链接,在苹果开发者中心创建app之后就会有

格式如下:https://apps.apple.com/cn/app/idxxxxxxxxxx​​​​​​

Bundle ID:在iOS项目这里获取:

填写完如下:

至此,平台上的安卓和IOS的基本配置就完成了,接下来是增加登录套件。

点击【Add products】

选择Login Kit

 然后在这里分别配置安卓和IOS的Redirect URI回调,这个网络上资料很多,各位自行去查找吧,配置好放在这里就可以了

重要提醒:截止到2024年2月7日,TikTok新版本的登录套件在iOS端是使用swfit集成的,唤醒Tiktok登录授权成功之后使用iOS Universal Link 来将用户信息回调给app; 在安卓端是使用Kotlin写的,使用Android App Link将用户信息回调给app,如果使用新版本的话,需要单独在每个端去集成TikTok登录,然后在Flutter中使用channel通道与原生app通信来获取Tiktok授权后的用户基本信息。

新版本文档在这里:

https://developers.tiktok.com/doc/overview/

这里使用的Flutter的第三方库使用的是老版本的登录套件,老版本在IOS端是用OC写的,在安卓端是用JAVA写的,如果你跟我一样使用的是Flutter的第三方库,那么请继续往下看,如果你的项目想用新版本的话,那么我们的缘分就到这里,本篇文章下面的内容可以略过了~

老版本的文档在这里:https://developers.tiktok.com/doc/getting-started-ios-quickstart-objective-c/

二 Flutter 第三方库配置

项目使用的dart环境

dart环境:sdk: '>=2.7.0 <3.0.0'

flutter 中使用的 tiktok登录插件有两个:

flutter_tiktok_sdk: ^0.2.6
dio: ^3.0.0

是的,这里还需要用dio网络请求的组件,原因为什么后面会讲,

flutter_tiktok_sdk插件的地址在这:flutter_tiktok_sdk | Flutter package

dio库的地址就不贴了,不是本篇的重点

直接添加到项目库里,然后执行flutter pub get

记得分别在ios端执行pod install 以及安卓端执行 gradle sync 来同步代码

三 IOS端APP配置

1.在Info.plist文件里增加如下信息:(引用自官方文档 https://developers.tiktok.com/doc/getting-started-ios-quickstart-objective-c/)

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>tiktokopensdk</string>
    <string>tiktoksharesdk</string>
    <string>snssdk1180</string>
    <string>snssdk1233</string>
</array>
<key>TikTokAppID</key>
<string>$TikTokAppID</string>
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>$TikTokAppID</string>
    </array>
  </dict>
</array>

但是你不要相信他,因为这里是错的,格式没问题,但是这里的TiktokAppID,全部都应该是Client key,他在欺骗你!!

Client Key在这里:

2.配置完iOS的Info.plist文件应如下所示:

3.在APPDelegate文件夹里添加如下代码:

#import <TikTokOpenSDK/TikTokOpenSDKAuth.h>
[[TikTokOpenSDKApplicationDelegate sharedInstance] application:application didFinishLaunchingWithOptions:launchOptions];

添加完如下所示:

iOS端就配置完了

四 安卓端配置

1.在AndroidManifest.xml添加如下代码

    <activity
           android:name="com.k9i.flutter_tiktok_sdk.TikTokEntryActivity"
           android:exported="true" />

文件位置及添加完效果如下所示:

2.还是在这个文件里,添加如下代码:

 <queries>
        <package android:name="com.zhiliaoapp.musically" />
        <package android:name="com.ss.android.ugc.trill" />
    </queries>

位置如图:

3.去build.gradle(project)文件添加如下代码:

maven { url "https://artifact.bytedance.com/repository/AwemeOpenSDK" }

添加完如图所示: 

4.去build.gradle(app)文件添加如下代码:

dependencies {
        implementation 'com.bytedance.ies.ugc.aweme:opensdk-oversea-external:0.2.1.2'
    }

添加完如下所示:

5.添加完成之后点击gradle sync同步框架,点击这里,记得翻墙

6.然后去MainActivity添加如下代码:

 String clientKey = "[你的Client key]";
 TikTokOpenConfig tiktokOpenConfig = new TikTokOpenConfig(clientKey);
 TikTokOpenApiFactory.init(tiktokOpenConfig);

位置及添加完效果如下所示:

截图里的类引用我也贴出来了,这两个类库如果没自动导入的话可以手动引入一下,好人快夸我。

import com.bytedance.sdk.open.tiktok.TikTokOpenApiFactory;
import com.bytedance.sdk.open.tiktok.TikTokOpenConfig;

五 Flutter Tiktok登录代码调用

打开Flutter项目

在项目入口调用:(来自第三方插件的示例)

 TikTokSDK.instance.setup(clientKey: 'TikTokAppID');

注意第三方插件这里也有个坑,第三方的示例文档写的是TikTokAppID,但是这里填的不是APPID,而是Client Key ,估计这开发插件的老哥的占位符写错了,注意啊,踩坑踩坑!

clientKey在这里获取:

添加完代码里是这样

接下来就要开始调用TikTok登录了,先说明一下Tiktok登录授权的逻辑。

理解这个流程很重要他不像国内的微信微博或者国外的facebook、谷歌的登录套件调用登录API之后直接就返回用户信息,而是需要进行三步操作:

第一步:调用Tiktok提供的登录api获取到用户的authCode(在其他的平台这一步就直接拿到用户信息了)

第二步:使用第一步获取到的authCode调用Tiktok提供的官方查询接口去获取accesstoken

第三步:使用第二步获取到的accesstoken再次调用Tiktok提供的查询接口去查询用户信息

怎么样,这个流程是不是感觉有点难受,但是放心,坑我都踩过了,我们一步一步来:

第一步:调用Tiktok提供的登录api获取到用户的authCode

final result = await TikTokSDK.instance.login(
  permissions: {
    TikTokPermissionType.userInfoBasic,
  },
);
if(result.status == TikTokLoginStatus.success){
​​​​​​​  print("获取authCode ==" + result.authCode);
}else{
  print("tiktok 登录失败 " + result.errorMessage);
}

调用成功后获取到的结果如下:

可以看到authCode已经正常返回了

第二步:调用Tiktok提供的查询接口查询accesstoken

文档地址:https://developers.tiktok.com/doc/legacy-user-access-guide/

需要传入的参数说明:

client_key :如下截图

client_secret:如下截图

code:传第一步获取到的 authCode

grant_type:固定传【authorization_code】

注意坑点来了:官方文档示例写的是Post,但是如果你用Post请求,是直接失败的,会返回307的错误,在这个地方,你要用Get请求,血泪坑啊,不要封装参数什么的,就用最原始的方法拼接请求链接,才可以正常获取结果

代码示例如下:

/*
  * TikTok获取accessToken
  * */
  static Future<Map<dynamic, dynamic>> getTikTokAccessToken({String authCode}) async {
    String requestUrl = "https://open-api.tiktok.com/oauth/access_token?client_key=aw7p7k5kjcuhthn9&client_secret=pf0kTB5lMjFaQioQYco3mt1FAxpdaNMs&code=" + Uri.decodeFull(authCode) + "&grant_type=authorization_code";
    Dio dio = Dio();
    final option = Options(
      method: "get",
    );
    Response response = await dio.request(requestUrl,options: option);

    Map<dynamic, dynamic> mapResult;
    if (response.data is String) {
      mapResult = convert.jsonDecode(response.data);
    } else {
      mapResult = response.data as Map;
    }
    return mapResult;
  }

调用后返回结果如下:

可以看到access_token已经正常返回了

第三步:使用accesstoken再次调用Tiktok提供的查询接口去查询用户信息

官方文档如下:

地址 https://developers.tiktok.com/doc/tiktok-api-v1-user-info/

注意里面的这个fields参数,这里传递的是你想查询的用户信息字段,下面有说明:

想要什么就去传什么字段,查询方法也封装好了,拿去用:

/*
  * TikTok获取用户信息
  * */
  static Future<Map<String, dynamic>> getTikTokUserInfo({String accessToken}) async {
    Map<String, dynamic> arguments = Map();
    arguments["access_token"] = accessToken;
    arguments["fields"] = ["open_id", "union_id", "avatar_url","display_name"];

    Dio dio = Dio();

    Map<String, dynamic> headers = Map();
    // headers["content-Type"] = "application/json";

    final option = Options(
      method: "post",
    );

    Response response = await dio.request(tikTokGetUserInfoUrl,data: arguments,options: option);

    Map<dynamic, dynamic> mapResult;
    if (response.data is String) {
      mapResult = convert.jsonDecode(response.data);
    } else {
      mapResult = response.data as Map;
    }
    return mapResult;
  }

调用成功之后返回信息如下:

至此,TikTok的登录就完成了。

源码地址:https://github.com/TheRuningAnt/FGTALogin.git

(该源码配置的TikTok项目未审核通过,所以点击登录会提示失败,但是该项目已经使用审核通过的TikTok项目项目参数key,appid等替换验证,可以正常实现Tiktok的登录授权,所以配置和调用方式可以直接参考)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1441190.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

macOS Sonoma 14.3.1(23D60)发布

系统介绍 黑果魏叔2 月 9 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 14.3.1 更新&#xff08;内部版本号&#xff1a;23D60&#xff09;&#xff0c;本次更新距离上次发布隔了 17 天。 魏叔 查询苹果官方更新日志&#xff0c;macOS Sonoma 14.3.1 修复内容和 …

MySQL之体系结构

华子目录 MySQL简介MySQL的特性MySQL版本MySQL常见版本 数据库排名网站MySQL结构体系查看最大连接数查询缓存配置情况 一条SQL语句执行流程 MySQL简介 MySQL是一个小型关系数据库管理系统&#xff0c;开发者为瑞典MySQL AB公司。在2008年1月16号被sun公司10亿美金收购。2009年…

8868体育助力法甲巴黎圣日耳曼俱乐部 运作球员转会

法甲的巴黎圣日耳曼足球俱乐部是8868的体育助力球队之一&#xff0c;根据法国媒体RMC的消息&#xff0c;巴黎圣日尔曼仍然希望在一月份增强球队的后防实力。虽然之前球队已经从圣保罗引进了20岁的巴西中后卫卢卡斯-贝拉尔多&#xff0c;而这名小将也将会是巴黎圣日耳曼冬窗的一…

放假--寒假自学版 day1(补2.5)

fread 函数&#xff1a; 今日练习 C语言面试题5道~ 1. static 有什么用途&#xff1f;&#xff08;请至少说明两种&#xff09; 1) 限制变量的作用域 2) 设置变量的存储域 2. 引用与指针有什么区别&#xff1f; 1) 引用必须被初始化&#xff0c;指针不必。 2) 引用初始…

QML用ListView实现带section的GridView

QML自带的GridView只能定义delegate&#xff0c;没有section&#xff0c;类似手机相册带时间分组标签的样式就没法做。最简单的方式就是组合ListViewGridView&#xff0c;或者ListViewFlow&#xff0c;但是嵌套View时&#xff0c;子级View一般是完全展开的&#xff0c;只显示该…

解决dockor安装nginx提示missing signature key的问题

问题描述 使用dockor安装nginx拉取nginx的时候提示key丢失问题 问题定位 由于dockor版本低导致 问题解决 卸载重新安装最新版本dockor 解决步骤 1. 卸载旧版本的Docker&#xff1a; sudo yum remove docker docker-common docker-selinux docker-engine 2. 安装依赖包&am…

Stable Diffusion教程——使用TensorRT GPU加速提升Stable Diffusion出图速度

概述 Diffusion 模型在生成图像时最大的瓶颈是速度过慢的问题。为了解决这个问题&#xff0c;Stable Diffusion 采用了多种方式来加速图像生成&#xff0c;使得实时图像生成成为可能。最核心的加速是Stable Diffusion 使用了编码器将图像从原始的 3512512 大小转换为更小的 46…

【杂谈】年尾做了这件事,我后悔了.......

文章目录 前言1. 花钱1.1 购买并安装幻兽帕鲁1.2 阿里云服务器 2. 配置3. 游玩4. 总结与感悟4.1 总结4.2 感悟 后记 幻兽帕鲁多人服务器部署 趁着过年放假&#xff0c;一本正经地玩游戏学习服务器部署啦&#xff01; 但是&#xff0c;部署完我就后悔了… 前言 作为一名 游戏…

shellcode

生成shellcode 在漏洞利用中&#xff0c;shellcode是不可或缺的部分&#xff0c;所以在网上有许多公开分享的 shellcode &#xff0c;在不同平台上并不通用&#xff0c;需要选择适合的shellcode 。这里推荐两个常 见公开的安全平台&#xff1a;一个为公开的漏洞库exploit-db&am…

【汇编】简单的linux汇编语言程序

一、Linux系统汇编语言 Linux系统上的汇编语言可以使用不同的语法风格&#xff0c;主要包括Intel语法和AT&T语法。这两种语法有各自的特点和风格区别&#xff0c;尽管它们表示的底层机器指令相同。下面分别对两种语法进行简要说明&#xff1a; Intel语法 Intel语法是由I…

深入理解ES的倒排索引

目录 数据写入过程 词项字典 term dictionary 倒排表 posting list FOR算法 RBM算法 ArrayContainer BitMapContainer 词项索引 term index 在Elasticsearch中&#xff0c;倒排索引的设计无疑是惊为天人的&#xff0c;下面看下倒排索引的结构。 倒排索引分为词项索引【…

【高频前端面试题--TypeScript篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;前端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 高频前端面试题--Vue3.0篇 什么是TypeScript&#xff1f;TypeScript数据类型TypeScript中命名空…

[word] word 2010宏已被禁用警告关闭方法 #媒体#学习方法

word 2010宏已被禁用警告关闭方法 Word2010宏已被禁用警告关闭方法&#xff1a;在「信任中心设置」选项的宏设置中选择「禁用所有宏&#xff0c;并且不通知」即可。 每次打开Word 2010&#xff0c;都会提示「完全警告&#xff1a;宏已被禁用」提示。自从Word 2010安装完毕&am…

JavaScript鼠标移动事件

&#x1f9d1;‍&#x1f393; 个人主页&#xff1a;《爱蹦跶的大A阿》 &#x1f525;当前正在更新专栏&#xff1a;《VUE》 、《JavaScript保姆级教程》、《krpano》、《krpano中文文档》 ​ ​ ✨ 前言 鼠标移动是用户界面中非常重要的交互行为。学习区分不同的鼠标移动事…

Vue事件中如何使用 event 对象

在Vue中&#xff0c;事件处理函数常常需要获取事件触发时的相关信息&#xff0c;比如鼠标位置、按键信息等。而要获取这些信息&#xff0c;就需要使用event对象。那么在Vue的事件中如何正确使用event对象呢&#xff1f;接下来就来详细介绍一下。 首先&#xff0c;在Vue的事件中…

ChatGLM2-6B模型的win10测试笔记

ChatGLM2-6B介绍&#xff1a; 介绍 ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本&#xff0c;在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上&#xff0c;ChatGLM2-6B 引入了如下新特性&#xff1a; 更强大的性能&#xff1a;基于 ChatGLM 初…

#Js篇:js里面递归的理解

定义&#xff1a; 递归是一种编程技术&#xff0c;它是指一个函数在其定义内部调用自身的过程。 特点&#xff1a; 一个问题可以分解为更小的问题用同样的方法解决&#xff1b;分解后的子问题求解方式一样&#xff0c;不同的是数据规模变小&#xff1b;存在递归终止条件 作…

前端JavaScript篇之原型链的终点是什么?如何打印出原型链的终点?

目录 原型链的终点是什么&#xff1f;如何打印出原型链的终点&#xff1f; 原型链的终点是什么&#xff1f;如何打印出原型链的终点&#xff1f; 在 JavaScript 中&#xff0c;原型链是由对象和原型对象组成的链式结构。每个对象都有一个原型对象&#xff0c;并通过 __proto__…

ruoyi若依框架SpringSecurity实现分析

系列文章 ruoyi若依框架学习笔记-01 ruoyi若依框架分页实现分析 ruoyi若依框架SpringSecurity实现分析 文章目录 系列文章前言具体分析一、项目中的SpringSecurity版本二、登录认证流程分析三、权限鉴定四、退出登录五、SpringSecurity配置类 总结 前言 在ruoyi-vue若依框…

JavaScript综合练习2

JavaScript 综合练习 2 1. 案例演示 2. 代码实现 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title&…