Flutter Kakao SDK集成插件test_kakao_flutter_sdk的使用

Flutter Kakao SDK集成插件 test_kakao_flutter_sdk 的使用

Kakao Flutter SDK

Flutter SDK for Kakao API. 目前支持 AndroidiOS 平台,并将在未来支持 web 平台(仍在测试阶段)。


检查清单:Flutter Web 支持

要启用 Kakao Flutter SDK 的 Web 支持,需要完成以下步骤:

  • ✅ 区分 JavaScript 环境的 KA 头部
  • ✅ 使用 window.open() 进行授权(默认方法)
  • ❌ 提供通过 location.href 授权的方式
  • ❌ 允许 Kakao API 服务器的跨域访问(CORS)
  • ❌ 在支持 Web 的情况下发布

注意:由于 KakaoTalk 登录需要轮询访问令牌等复杂机制,因此目前在 Web 上不可用。


开始使用

Flutter 正在成为跨平台开发的强大工具,因为它可以从单一代码库生成移动、Web 和桌面应用。对于 Kakao API 的 Flutter 支持请求,这里有一个解决方案。

flutter_kakao_login 插件不同,该插件旨在用 Dart 重写 Kakao SDK,尽可能减少平台依赖代码。


依赖项

首先,在项目中引入 Kakao Flutter SDK,编辑 pubspec.yaml 文件并添加以下依赖:

dependencies:
  kakao_flutter_sdk: ^0.7.1

Kakao Flutter SDK 的依赖项包括:

  1. dio (4.0.0)
  2. json_annotation (4.0.1)
  3. shared_preferences (2.0.5)
  4. platform (3.0.0)
  5. package_info (2.0.0)

一些被考虑但最终移除的依赖项包括:

  1. url_launcher
  2. flutter_custom_tabs
  3. flutter_web_auth

提示:这些库虽然简化了 Android 和 iOS 的通用接口,但不适合涉及默认浏览器的 OAuth 2.0 流程。SDK 原生调用了 Chrome Custom TabsASWebAuthenticationSession 来进行 OAuth 2.0 认证。


Kakao 应用程序设置

Kakao Developers 创建应用程序并配置 Android 和 iOS 平台。

步骤:

  1. Android 入门指南
  2. iOS 入门指南
  3. Web 入门指南

此外,还需完成以下额外步骤:

  1. 注册 Key Hash 以使用 Kakao API。
  2. 设置 plist 和 URL Scheme

最低支持的 iOS 版本为 11。因此,需要在 Podfile 中指定为 11:

platform :ios, '11.0'

否则可能会遇到错误,例如:

[CocoaPods] Could not find compatible versions for pod "kakao_flutter_sdk":

实现指南

初始化 SDK

在应用启动时初始化 SDK,只需将原生应用密钥设置到全局上下文中。

KakaoContext.clientId = "${put your native app key here}";
// KakaoContext.javascriptClientId = "${put your javascript key here}"; // 尚未支持
Kakao 登录

现在可以使用 UserApi 中的 loginWithKakaoTalk()loginWithKakaoAccount() 方法。

// 使用 KakaoTalk 登录 (0.6.4 及以上版本)
void loginButtonClicked() async {
  try {
    await UserApi.instance.loginWithKakaoTalk();
    // 登录后的操作
  } catch (e) {
    print('登录错误: $e');
  }
}

如果使用 loginWithKakaoAccount(),请确保在 Kakao Developers 设置中启用了“通过浏览器”。

// 使用 KakaoAccount 登录 (0.6.4 及以上版本)
void loginButtonClicked() async {
  try {
    await UserApi.instance.loginWithKakaoAccount();
    // 登录后的操作
  } catch (e) {
    print('登录错误: $e');
  }
}

可以强制用户重新认证以增强安全性,设置 promptsPrompt.LOGIN

// 强制用户重新登录
void loginButtonClicked() async {
  try {
    await UserApi.instance.loginWithKakaoAccount(prompts: [Prompt.LOGIN]);
    // 登录后的操作
  } catch (e) {
    print('登录错误: $e');
  }
}

获取授权码

用户可以通过两种方式获取授权码:

  1. 通过浏览器登录 Kakao 账户。
  2. 通过 KakaoTalk 登录。
通过浏览器

SDK 使用 ASWebAuthenticationSessionCustom Tabs 打开浏览器。

void loginButtonClicked() async {
  try {
    String authCode = await AuthCodeClient.instance.request();
    // 处理授权码
  } on KakaoAuthException catch (e) {
    // 登录过程中发生错误
  } on KakaoClientException catch (e) {
    // 其他客户端异常
  } catch (e) {
    // 其他错误
  }
}

Android 注意事项:默认浏览器会通过自定义方案将授权码重定向回您的应用。因此,必须在 AndroidManifest.xml 中添加以下配置:

<activity android:name="com.kakao.sdk.flutter.AuthCodeCustomTabsActivity">
  <intent-filter android:label="flutter_web_auth">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data android:scheme="kakao${your_native_app_key_here}" android:host="oauth"/>
  </intent-filter>
</activity>

更多信息可参考 示例代码

通过 KakaoTalk
void loginButtonClicked() async {
  try {
    String authCode = await AuthCodeClient.instance.requestWithTalk();
    // 处理授权码
  } on KakaoAuthException catch (e) {
    // 登录过程中发生错误
  } on KakaoClientException catch (e) {
    // 其他客户端异常
  } catch (e) {
    // 其他错误
  }
}

获取访问令牌

有了授权码后,需要向 Kakao API 发起请求以获取访问令牌。

void loginButtonClicked() async {
  try {
    String authCode = await AuthCodeClient.instance.request(); // 通过浏览器
    // String authCode = await AuthCodeClient.instance.requestWithTalk(); // 或通过 KakaoTalk
    AccessTokenResponse token = await AuthApi.instance.issueAccessToken(authCode);
    AccessTokenStore.instance.toStore(token); // 存储访问令牌以便后续 API 请求。
  } catch (e) {
    // 登录过程中发生错误
  }
}

检查令牌状态

首次登录后,可以通过检查 AccessTokenStore 来跳过此过程。

AccessToken token = await AccessTokenStore.instance.fromStore();
if (token.refreshToken == null) {
  Navigator.of(context).pushReplacementNamed('/login'); // 跳转到登录页面
} else {
  Navigator.of(context).pushReplacementNamed("/main"); // 跳转到主界面
}

提示:刷新令牌的存在是判断用户是否需要重新授权的良好标准,因为刷新令牌可用于刷新访问令牌。


调用基于令牌的 API

确保访问令牌存在后,可以调用基于令牌的 API。

用户 API 示例

以下是一个调用 /v2/user/me API 的示例。

try {
  User user = await UserApi.instance.me();
  // 对用户实例执行所需操作
} on KakaoAuthException catch (e) {
  if (e.code == ApiErrorCause.INVALID_TOKEN) { // 访问令牌已过期且无法刷新
    Navigator.of(context).pushReplacementNamed('/login'); // 跳转到登录页面
  }
} catch (e) {
  // 其他 API 或客户端错误
}
动态用户协议

某些 API 需要用户同意才能调用。

当返回 403 Forbidden 错误时

如果 Kakao Flutter SDK 版本为 0.7.0 或更高,则会自动弹出额外的同意窗口。

Future<void> requestFriends() async {
  try {
    FriendsResponse friends = await TalkApi.instance.friends();
    // 对朋友列表执行所需操作
  } on KakaoAuthException catch (e) {
    if (e.code == ApiErrorCause.INVALID_TOKEN) {
      Navigator.of(context).pushReplacementNamed('/login');
    } else if (e.code == ApiErrorCause.INSUFFICIENT_SCOPE) {
      // 如果需要更多范围,请重新获取令牌
    }
  } catch (e) {
    // 其他错误
  }
}
某些字段缺失时

当调用 /v2/user/me API 时,某些字段可能缺失。

void requestMe() async {
  try {
    User user = await UserApi.instance.me();
    if (user.kakaoAccount.emailNeedsAgreement || user.kakaoAccount.genderNeedsAgreement) {
      // 邮箱和性别可以在用户同意后获取
      await retryAfterUserAgrees(["account_email", "gender"]);
      return;
    }
    // 对用户实例执行所需操作
  } on KakaoAuthException catch (e) {
    if (e.code == ApiErrorCause.INVALID_TOKEN) {
      Navigator.of(context).pushReplacementNamed('/login');
    }
  } catch (e) {
    // 其他错误
  }
}

Future<void> retryAfterUserAgrees(List<String> requiredScopes) async {
  String authCode = await AuthCodeClient.instance.requestWithAgt(requiredScopes);
  AccessTokenResponse token = await AuthApi.instance.issueAccessToken(authCode);
  AccessTokenStore.instance.toStore(token);
  await requestMe();
}

基于 App Key 的 API

以下是一些仅需初始化 SDK 后即可调用的 API。

  1. LinkApi
  2. LocalApi
  3. SearchApi
  4. PushApi
KakaoLink 示例
import 'package:kakao_flutter_sdk/main.dart';

Uri uri = await LinkClient.instance
          .custom(16761, templateArgs: {"key1": "value1"});
await launchBrowserTab(uri);
KakaoNavi 示例
void _navigationButtonClicked() async {
  try {
    var url = await NaviApi.instance
        .navigateWebUrl(Location("카카오 판교오피스", "321286", "533707"));
    print(url);
    await launchBrowserTab(url);
  } catch (e) {
    print(e);
  }
}
1 回复

更多关于Flutter Kakao SDK集成插件test_kakao_flutter_sdk的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中集成Kakao SDK,你可以使用 test_kakao_flutter_sdk 插件。这个插件允许你在Flutter应用中与Kakao的API进行交互,例如登录、分享、消息发送等功能。以下是如何使用 test_kakao_flutter_sdk 插件的步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 test_kakao_flutter_sdk 插件的依赖。

dependencies:
  flutter:
    sdk: flutter
  test_kakao_flutter_sdk: ^latest_version

然后运行 flutter pub get 来获取依赖。

2. 配置Kakao SDK

android/app/src/main/AndroidManifest.xml 文件中添加以下配置:

<application>
    <meta-data
        android:name="com.kakao.sdk.AppKey"
        android:value="YOUR_KAKAO_APP_KEY" />
</application>

ios/Runner/Info.plist 文件中添加以下配置:

<key>KAKAO_APP_KEY</key>
<string>YOUR_KAKAO_APP_KEY</string>

3. 初始化Kakao SDK

在你的Flutter应用的 main.dart 文件中初始化Kakao SDK。

import 'package:flutter/material.dart';
import 'package:test_kakao_flutter_sdk/kakao_sdk.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await KakaoSdk.init(nativeAppKey: 'YOUR_KAKAO_APP_KEY');
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Kakao SDK Example',
      home: HomeScreen(),
    );
  }
}

4. 使用Kakao登录

你可以使用 test_kakao_flutter_sdk 插件来实现Kakao登录功能。

import 'package:flutter/material.dart';
import 'package:test_kakao_flutter_sdk/auth.dart';

class HomeScreen extends StatelessWidget {
  Future<void> _kakaoLogin() async {
    try {
      final OAuthToken token = await AuthApi.instance.login();
      print('Kakao Login Success: ${token.accessToken}');
    } catch (e) {
      print('Kakao Login Failed: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kakao SDK Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _kakaoLogin,
          child: Text('Login with Kakao'),
        ),
      ),
    );
  }
}

5. 使用Kakao分享

你可以使用 test_kakao_flutter_sdk 插件来实现Kakao分享功能。

import 'package:flutter/material.dart';
import 'package:test_kakao_flutter_sdk/share.dart';

class HomeScreen extends StatelessWidget {
  Future<void> _kakaoShare() async {
    try {
      final Uri uri = Uri.parse('https://flutter.dev');
      await ShareClient.instance.shareDefault(uri: uri);
      print('Kakao Share Success');
    } catch (e) {
      print('Kakao Share Failed: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Kakao SDK Example'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _kakaoShare,
          child: Text('Share with Kakao'),
        ),
      ),
    );
  }
}

6. 处理Kakao回调

android/app/src/main/AndroidManifest.xml 文件中添加以下配置以处理Kakao回调:

<activity
    android:name="com.kakao.sdk.flutter.KakaoSdkFlutterActivity"
    android:launchMode="singleTask">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:host="oauth" android:scheme="kakaoYOUR_KAKAO_APP_KEY" />
    </intent-filter>
</activity>

ios/Runner/Info.plist 文件中添加以下配置以处理Kakao回调:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>kakaoYOUR_KAKAO_APP_KEY</string>
        </array>
    </dict>
</array>
回到顶部