Flutter Kakao账号登录插件sign_in_with_kakao的使用

发布于 1周前 作者 vueper 来自 Flutter

Flutter Kakao 계정 로그인 플러그인 sign_in_with_kakao의 사용

Sign in with Kakao

pub package

카카오 SDK를 활용하여 로그인 v2 기능을 지원하는 플러그인입니다.

참고: 해당 플러그인은 카카오에서 공식적으로 제공하지 않는 것입니다.
공식 플러그인을 사용하고 싶으신 경우 아래의 플러그인을 참조해주세요.
👉 Official Links


지원되는 플랫폼

  • Android 21 이상
  • iOS 11 이상

기능

  • ✅ 카카오톡으로 로그인
  • ✅ 카카오계정으로 로그인
  • ✅ 로그아웃
  • ✅ 연결끊기
  • ✅ 토큰정보 보기
  • ✅ 사용자 정보 가져오기
  • ✅ 사용자 정보 저장하기
  • ❌ 추가 항목 동의 받기

시작하기

플러그인의 자세한 사용법은 example 디렉토리를 참조해주세요.

1. pubspec.yaml에 추가
dependencies:
  sign_in_with_kakao: latest_version
2. 애플리케이션 등록

카카오 SDK를 사용하기 위해서는 애플리케이션을 먼저 등록해야 합니다. 아래 링크를 참고하여 등록하세요.
👉 애플리케이션 등록

3. 카카오 로그인 설정

카카오 로그인 설정을 완료하기 위한 절차는 아래 링크를 참고하세요.
👉 카카오 로그인 설정하기

4. Android 설정
(1) 키 해시 등록

안드로이드에서 카카오 로그인을 사용하려면 키 해시를 등록해야 합니다.
👉 안드로이드 키 해시 등록

(2) AndroidManifest.xml 설정
<application>
    <!-- 플러터 플러그인 v2 버전만 지원합니다. -->
    <meta-data
      android:name="flutterEmbedding"
      android:value="2" />

    <!-- 카카오 SDK 초기화 과정에 사용됩니다. -->
    <meta-data
      android:name="plugin.dev.juyoung.kakao.KakaoAppKey"
      android:value="네이티브 앱 키를 입력해주세요." />

    <!-- 카카오 로그인 처리에 사용됩니다. -->
    <activity android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity">
      <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="kakao{NATIVE_APP_KEY}" />
      </intent-filter>
    </activity>
</application>
5. iOS 설정
(1) Info.plist 설정
<plist version="1.0">
<dict>
    <!-- 카카오 SDK 초기화 과정에 사용됩니다. -->
    <key>KakaoAppKey</key>
    <string>네이티브 앱 키를 입력해주세요.</string>
    <!-- 카카오 인증을 통한 앱 실행에 사용됩니다. -->
    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleTypeRole</key>
            <string>Editor</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>kakao{NATIVE_APP_KEY}</string>
            </array>
        </dict>
    </array>
    <!-- 카카오 애플리케이션 실행을 위해 사용됩니다. -->
    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>kakaokompassauth</string>
        <string>kakaolink</string>
    </array>
</dict>
</plist>

예제 코드

아래는 sign_in_with_kakao 플러그인을 사용한 간단한 예제입니다. 이 코드는 카카오 로그인, 로그아웃, 연결끊기를 포함하고 있습니다.

main.dart
import 'package:flutter/material.dart';
import 'package:shimmer/shimmer.dart';
import 'package:sign_in_with_kakao/sign_in_with_kakao.dart';

void main() {
  runApp(SignInWithKakaoDemo());
}

class SignInWithKakaoDemo extends StatefulWidget {
  [@override](/user/override)
  _SignInWithKakaoDemoState createState() => _SignInWithKakaoDemoState();
}

class _SignInWithKakaoDemoState extends State<SignInWithKakaoDemo> {
  final Color _buttonColor = Color(0xFFFEE500);
  final Color _buttonTextColor = Color(0xD9000000);

  late bool _isAuthorized;
  User? _user;

  [@override](/user/override)
  void initState() {
    super.initState();

    /// 프로퍼티 초기화
    _isAuthorized = false;
    _user = null;

    /// 토큰 정보 확인
    _accessTokenInfo();
  }

  void _updateIfNecessary(VoidCallback fn) {
    if (!mounted) {
      return;
    }

    setState(fn);
  }

  void _accessTokenInfo() async {
    try {
      final tokenInfo = await SignInWithKakao.accessTokenInfo();

      if (tokenInfo.expiresIn > 0) {
        _updateIfNecessary(() => _isAuthorized = true);
        _me();
      } else {
        _updateIfNecessary(() => _isAuthorized = false);
      }
    } catch (error) {
      _updateIfNecessary(() => _isAuthorized = false);
    }
  }

  void _login() async {
    try {
      final authToken = await SignInWithKakao.login();
      _updateIfNecessary(() {
        _isAuthorized = true;
      });
      _me();
    } catch (error) {
      /// 로그인 예외 처리
    }
  }

  void _me() async {
    try {
      await Future.delayed(const Duration(seconds: 2));
      final user = await SignInWithKakao.me();
      _updateIfNecessary(() => _user = user);
    } catch (error) {
      /// 로그인 예외 처리
    }
  }

  void _logout() async {
    final succeed = await SignInWithKakao.logout();

    if (!succeed) {
      return;
    }

    _updateIfNecessary(() {
      _isAuthorized = false;
      _user = null;
    });
  }

  void _unlink() async {
    final succeed = await SignInWithKakao.unlink();

    if (!succeed) {
      return;
    }

    _updateIfNecessary(() {
      _isAuthorized = false;
      _user = null;
    });
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData.light(),
      darkTheme: ThemeData.dark(),
      themeMode: ThemeMode.dark,
      home: Scaffold(
        appBar: AppBar(
          title: Text('Sign in with Kakao Demo'),
        ),
        body: _isAuthorized ? _buildProfileView() : _buildSignInView(),
      ),
    );
  }

  Widget _buildSignInView() {
    return Container(
      width: double.infinity,
      child: Center(
        child: ElevatedButton(
          child: Text('카카오 로그인'),
          onPressed: _login,
        ),
      ),
    );
  }

  Widget _buildProfileView() {
    return Container(
      width: double.infinity,
      child: Column(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          if (_user != null) _buildAccountView() else _buildLoadingView(),
          SizedBox(height: 24.0),
          ElevatedButton(
            child: Text('로그아웃'),
            onPressed: _logout,
          ),
          ElevatedButton(
            child: Text('연결끊기'),
            onPressed: _unlink,
          ),
        ],
      ),
    );
  }

  Widget _buildAccountView() {
    return Container(
      width: double.infinity,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          if (_user!.account!.profile!.thumbnailImageUrl != null)
            Container(
              width: 110.0,
              height: 110.0,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                image: DecorationImage(
                  image: NetworkImage(_user!.account!.profile!.thumbnailImageUrl!),
                  fit: BoxFit.cover,
                ),
              ),
            ),
          if (_user!.account!.profile!.thumbnailImageUrl == null)
            Container(
              width: 110.0,
              height: 110.0,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: Colors.grey,
              ),
              child: Icon(
                Icons.account_circle_rounded,
                size: 110.0,
              ),
            ),
          SizedBox(height: 16.0),
          Text(
            _user!.account!.profile!.nickname!,
            style: Theme.of(context)
                .textTheme
                .headline5!
                .copyWith(color: Colors.white),
          ),
        ],
      ),
    );
  }

  Widget _buildLoadingView() {
    return Container(
      width: double.infinity,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Shimmer.fromColors(
            child: Container(
              width: 110.0,
              height: 110.0,
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: Colors.red,
              ),
            ),
            baseColor: Colors.grey,
            highlightColor: Colors.grey[400]!,
          ),
          SizedBox(height: 16.0),
          Shimmer.fromColors(
            child: Text(
              '사용자 정보 조회 중...',
              style: Theme.of(context).textTheme.headline5,
            ),
            baseColor: Colors.grey,
            highlightColor: Colors.grey[400]!,
          ),
        ],
      ),
    );
  }
}

更多关于Flutter Kakao账号登录插件sign_in_with_kakao的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Kakao账号登录插件sign_in_with_kakao的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中使用Kakao账号登录,可以使用sign_in_with_kakao插件。这个插件提供了与Kakao SDK的集成,允许用户通过Kakao账号登录你的应用。以下是使用sign_in_with_kakao插件的步骤:

1. 添加依赖

首先,在pubspec.yaml文件中添加sign_in_with_kakao插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  sign_in_with_kakao: ^1.0.0  # 请检查最新版本

然后运行flutter pub get来安装依赖。

2. 配置Kakao开发者平台

在Kakao开发者平台上注册你的应用,并获取Native App Key。你还需要配置应用的Redirect URI,通常为kakao{NATIVE_APP_KEY}://oauth

3. 配置Android

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

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <application>
        <activity android:name="com.kakao.sdk.flutter.AuthCodeCustomTabsActivity"
            android:exported="true">
            <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{NATIVE_APP_KEY}" />
            </intent-filter>
        </activity>
    </application>
</manifest>

{NATIVE_APP_KEY}替换为你在Kakao开发者平台上获取的Native App Key

4. 配置iOS

ios/Runner/Info.plist文件中添加以下内容:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>kakao{NATIVE_APP_KEY}</string>
        </array>
    </dict>
</array>

同样,将{NATIVE_APP_KEY}替换为你在Kakao开发者平台上获取的Native App Key

5. 初始化Kakao SDK

main.dart文件中初始化Kakao SDK:

import 'package:flutter/material.dart';
import 'package:sign_in_with_kakao/sign_in_with_kakao.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: LoginScreen(),
    );
  }
}

6. 实现登录功能

在登录页面中,使用SignInWithKakao类来实现登录功能:

import 'package:flutter/material.dart';
import 'package:sign_in_with_kakao/sign_in_with_kakao.dart';

class LoginScreen extends StatelessWidget {
  Future<void> _signInWithKakao() async {
    try {
      final OAuthToken token = await SignInWithKakao.login();
      print('Kakao Login Success: ${token.accessToken}');
      // 你可以在这里处理登录成功后的逻辑,例如保存token或跳转到主页
    } catch (error) {
      print('Kakao Login Failed: $error');
    }
  }

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

7. 处理登录结果

_signInWithKakao方法中,你可以处理登录成功或失败的情况。登录成功后,你可以获取到OAuthToken,其中包含了访问令牌(accessToken)和刷新令牌(refreshToken),你可以将这些令牌保存起来,用于后续的API请求。

8. 登出功能

如果你需要实现登出功能,可以使用以下代码:

Future<void> _signOutWithKakao() async {
  try {
    await SignInWithKakao.logout();
    print('Kakao Logout Success');
    // 你可以在这里处理登出成功后的逻辑,例如清除用户数据或跳转到登录页面
  } catch (error) {
    print('Kakao Logout Failed: $error');
  }
}

9. 处理用户信息

你可以使用Kakao的API来获取用户信息。首先,你需要确保用户已经授权了profileaccount_email等权限。然后,你可以使用以下代码来获取用户信息:

Future<void> _getUserInfo() async {
  try {
    final User user = await SignInWithKakao.getUserInfo();
    print('User Info: ${user.toJson()}');
    // 你可以在这里处理用户信息,例如显示用户昵称或头像
  } catch (error) {
    print('Failed to get user info: $error');
  }
}
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!