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

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

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

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
 
 
Share article
RSSPowered by inblog