inblog logo
|
vosw1
    Flutter

    서버없이 Flutter로 카카오 로그인 구현하기

    송민경's avatar
    송민경
    Aug 23, 2024
    서버없이 Flutter로 카카오 로그인 구현하기

    1. pubspec.yaml에 라이브러리 추가하기

    kakao_flutter_sdk_user install | Flutter package
    A flutter plugin for Kakao API, which supports Kakao login, KakaoTalk Share, User API, KakaoTalk API and Navi API.
    kakao_flutter_sdk_user install | Flutter package
    https://pub.dev/packages/kakao_flutter_sdk_user/install
    kakao_flutter_sdk_user install | Flutter package
    http: ^1.2.2 oauth2: ^2.0.3 uni_links: 0.5.1 kakao_flutter_sdk: ^1.9.2 url_launcher: ^6.3.0
    kakao_flutter_sdk: ^1.6.1 # 전체 추가 kakao_flutter_sdk_user: ^1.6.1 # 카카오 로그인 kakao_flutter_sdk_talk: ^1.6.1 # 카카오톡 메시지, 카카오톡 소셜(프로필 가져오기, 친구 목록 가져오기) kakao_flutter_sdk_story: ^1.6.1 # 카카오스토리 kakao_flutter_sdk_share: ^1.6.1 # 카카오톡 공유 kakao_flutter_sdk_navi: ^1.6.1 # 카카오내비 kakao_flutter_sdk_friend: ^1.6.1 # 카카오톡 소셜(피커: 친구 선택하기)

    2. main.dart에서 초기화 시키기

    void main() { KakaoSdk.init(nativeAppKey: '네이티브 앱 키'); runApp(MyApp()); }
    • 전체 코드
    import 'package:flutter/material.dart'; import 'package:kakao_flutter_sdk/kakao_flutter_sdk.dart'; import 'oauth/login_page.dart'; void main() { KakaoSdk.init(nativeAppKey: '{네이티브 앱 키}'); runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, ), home: LoginPage(), ); } }
     

    3. lib/oauth/kakao_oauth_service.dart 추가하기

    import 'dart:convert'; import 'package:uni_links/uni_links.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:http/http.dart' as http; import 'package:flutter/material.dart'; class KakaoOAuthService { final String _authorizationEndpoint = 'https://kauth.kakao.com/oauth/authorize'; final String _tokenEndpoint = 'https://kauth.kakao.com/oauth/token'; final String _clientId = '9f7d79718257b5a77723a5f9906bbcec'; final String _redirectUri = 'kakao9f7d79718257b5a77723a5f9906bbcec://oauth'; // 로그인 메서드 Future<void> login(BuildContext context) async { try { print('========== 카카오 로그인 시작'); final authCode = await _getAuthorizationCode(); if (authCode != null) { print('========== 인증 코드 획득: $authCode'); await _requestToken(authCode, context); } else { throw '========== 인증 코드가 없습니다'; } } catch (e) { print('========== 로그인 오류: $e'); } } Future<String?> _getAuthorizationCode() async { final authorizationUrl = Uri.parse( '$_authorizationEndpoint?client_id=$_clientId&redirect_uri=$_redirectUri&response_type=code' ); print('========== 인증 URL 열기: $authorizationUrl'); if (await canLaunchUrl(authorizationUrl)) { await launchUrl(authorizationUrl); } else { throw '========== $authorizationUrl을 열 수 없습니다'; } // Try to get the initial link try { final initialLink = await getInitialLink(); if (initialLink != null) { final uri = Uri.parse(initialLink); final code = uri.queryParameters['code']; print('========== 추출된 코드: $code'); return code; } } catch (e) { print('========== 링크 처리 오류: $e'); } // Set up a listener for deep links (redirect URI) final initialLinkStream = uriLinkStream; await for (final link in initialLinkStream) { if (link != null) { final uri = Uri.parse(link as String); final code = uri.queryParameters['code']; print('========== 스트림에서 추출된 코드: $code'); if (code != null) return code; } } return null; } Future<void> _requestToken(String authCode, BuildContext context) async { final response = await http.post( Uri.parse(_tokenEndpoint), headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: { 'grant_type': 'authorization_code', 'client_id': _clientId, 'redirect_uri': _redirectUri, 'code': authCode, }, ); print('Token request status code: ${response.statusCode}'); if (response.statusCode == 200) { final data = jsonDecode(response.body); final accessToken = data['access_token']; print('========== 액세스 토큰: $accessToken'); _onLoginSuccess(context, accessToken); // 성공 시 추가 작업 수행 } else { throw '========== 액세스 토큰 요청 실패: ${response.body}'; } } void _onLoginSuccess(BuildContext context, String accessToken) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('로그인에 성공했습니다'), duration: Duration(seconds: 2), ), ); print('========== 로그인 성공! 액세스 토큰: $accessToken'); // Future.delayed(Duration(seconds: 2), () { // // 예: 다른 페이지로 이동하거나 추가 작업 수행 // // Navigator.of(context).pushReplacementNamed('/home'); // }); } }
     

    4. lib/oauth/login_page.dart 추가하기

    import 'package:flutter/material.dart'; import 'kakao_oauth_service.dart'; class LoginPage extends StatelessWidget { final KakaoOAuthService _kakaoService = KakaoOAuthService(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Login'), ), body: Center( child: ElevatedButton( onPressed: () async { await _kakaoService.login(context); }, style: ElevatedButton.styleFrom( foregroundColor: Colors.black, backgroundColor: Colors.yellow, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ SizedBox(width: 10), Text( 'Kakao 로그인', style: TextStyle(fontSize: 16), ), ], ), ), ), ); } }
    notion image
    notion image
     
    notion image
    notion image
     
    notion image
    notion image
    notion image
    notion image
     
    Kakao Developers
    카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.
    Kakao Developers
    https://developers.kakao.com/docs/latest/ko/kakaologin/trouble-shooting
    Kakao Developers
     
    Share article

    vosw1

    RSS·Powered by Inblog