우선 프로바이더 패키지를 설치하여 프로젝트에 적용시킵니다.
kakao_login_service.dart
이렇게 kakao_login_service.dart파일을 하나 생성해줍니다.
KakaoDevelopers의 문서 내용을 참고하여
// 카카오 로그인 구현 예제
// 카카오톡 실행 가능 여부 확인
// 카카오톡 실행이 가능하면 카카오톡으로 로그인, 아니면 카카오계정으로 로그인
if (await isKakaoTalkInstalled()) {
try {
await UserApi.instance.loginWithKakaoTalk();
print('카카오톡으로 로그인 성공');
} catch (error) {
print('카카오톡으로 로그인 실패 $error');
// 사용자가 카카오톡 설치 후 디바이스 권한 요청 화면에서 로그인을 취소한 경우,
// 의도적인 로그인 취소로 보고 카카오계정으로 로그인 시도 없이 로그인 취소로 처리 (예: 뒤로 가기)
if (error is PlatformException && error.code == 'CANCELED') {
return;
}
// 카카오톡에 연결된 카카오계정이 없는 경우, 카카오계정으로 로그인
try {
await UserApi.instance.loginWithKakaoAccount();
print('카카오계정으로 로그인 성공');
} catch (error) {
print('카카오계정으로 로그인 실패 $error');
}
}
} else {
try {
await UserApi.instance.loginWithKakaoAccount();
print('카카오계정으로 로그인 성공');
} catch (error) {
print('카카오계정으로 로그인 실패 $error');
}
}
이 구문은 로그인을 위한 로직입니다.
try {
await UserApi.instance.logout();
print('로그아웃 성공, SDK에서 토큰 삭제');
} catch (error) {
print('로그아웃 실패, SDK에서 토큰 삭제 $error');
}
그리고 이 구문은 로그아웃을 위한 로직입니다.
// 사용자 정보요청 로직
try {
user = await UserApi.instance.me();
print('사용자 정보 요청 성공'
'\n회원번호: ${user?.id}'
'\n닉네임: ${user?.kakaoAccount?.profile?.nickname}');
notifyListeners();
} catch (error) {
print('사용자 정보 요청 실패 $error');
}
공식문서에 나와있는 로직은 아니지만
사용자 정보요청 로직도 사용하여 회원번호와 닉네임을 받을수 있는 로직도 사용해보겠습니다.
// kakao_login_service.dart
class KakaoLoginService extends ChangeNotifier {
User? user;
Future<void> login() async {
if (await isKakaoTalkInstalled()) {
try {
await UserApi.instance.loginWithKakaoTalk();
print('카카오톡으로 로그인 성공');
await _fetchUserInfo(); // 사용자 정보 가져오기
} catch (error) {
print('카카오톡으로 로그인 실패 $error');
if (error is PlatformException && error.code == 'CANCELED') {
return;
}
try {
await UserApi.instance.loginWithKakaoAccount();
print('카카오계정으로 로그인 성공1');
await _fetchUserInfo(); // 사용자 정보 가져오기
} catch (error) {
print('카카오계정으로 로그인 실패1 $error');
}
}
} else {
try {
await UserApi.instance.loginWithKakaoAccount();
print('카카오계정으로 로그인 성공2');
await _fetchUserInfo(); // 사용자 정보 가져오기
} catch (error) {
print('카카오계정으로 로그인 실패2 $error');
}
}
notifyListeners();
}
Future<void> _fetchUserInfo() async {
try {
user = await UserApi.instance.me();
print('사용자 정보 요청 성공'
'\n회원번호: ${user?.id}'
'\n닉네임: ${user?.kakaoAccount?.profile?.nickname}');
notifyListeners();
} catch (error) {
print('사용자 정보 요청 실패 $error');
}
}
Future<void> logout() async {
try {
await UserApi.instance.logout();
print("로그아웃 성공");
user = null; // 사용자 정보 초기화
notifyListeners();
} catch (error) {
print("로그아웃 실패 $error");
}
}
}
그리고 provider에 있는 notifyListeners()를 활용하여 변경이 감지될시 알람이 주는 구문까지 추가하여 주겠습니다.
main.dart
runApp 내에 멀티프로바이더를 설정해주고
child 항목에 MyApp()을 넣습니다.
void main() {
WidgetsFlutterBinding.ensureInitialized();
KakaoSdk.init(nativeAppKey: '${YOUR NATIVE APP KEY}');
runApp(
MultiProvider(
providers: [
ChangeNotifierProvider(create: (context) => KakaoLoginService()),
],
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
homepage.dart
// 로그인 버튼
ElevatedButton(
onPressed: () {
Provider.of<KakaoLoginService>(context, listen: false).login();
},
child: Text("logout"))
// 로그아웃 버튼
ElevatedButton(
onPressed: () {
Provider.of<KakaoLoginService>(context, listen: false).logout();
},
child: Text("logout"))
이렇게 provider와 함께 KakaoLoginService를 사용하여 로그인, 로그아웃 버튼을 사용할 수 있습니다.
Provider.of<KakaoLoginService>(context, listen: false) 이 구문을 통해
provider패키지를 사용하여 KakaoLoginService 객체를 가져옵니다.
조금더 설명을 붙이자면
- Provider.of
- KakaoLoginService 타입의 프로바이더를 검색합니다.
- 이는 ChangeNotifier Provider나 Provider로 제공된 객체를 찾습니다.
- context
- 현재 위젯의 빌드 컨텍스트 입니다.
- 이를통해 트리 구조상 어디에서 Provider를 검색할지 결정합니다.
- listen : false
- 상태 변화에 대한 알림을 듣지 않겠다는 뜻입니다.
- false로 설정하면 이 컨텍스트는 상태변화에 반응하지 않습니다.
- 이는 보통 메서드 호출과 같이 단발성 작업에 사용됩니다.
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Kakao login"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
GestureDetector(
onTap: () {
Provider.of<KakaoLoginService>(context, listen: false).login();
},
child: ClipRRect(
borderRadius: BorderRadius.circular(50),
child: Image.network(
"https://cdn-icons-png.flaticon.com/512/3984/3984330.png",
height: 200,
width: 200,
),
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Provider.of<KakaoLoginService>(context, listen: false)
.logout();
},
child: Text("logout")),
Consumer<KakaoLoginService>(
builder: (context, kakaoLoginService, child) {
if (kakaoLoginService.user != null) {
return Text(
'환영합니다, ${kakaoLoginService.user?.kakaoAccount?.profile?.nickname}');
} else {
return Text('로그인해 주세요');
}
},
),
],
),
),
);
}
}
이렇게 카카오톡 로그인을 구현해보았습니다.
카카오톡으로 간편 가입같은 경우는 테스트앱이 아닌 비즈앱으로 변경했어야 했기때문에 시도해보진 못했으나 다음에 기회가 있으면 한번 해보고싶습니다.
'Flutter > tip' 카테고리의 다른 글
[플러터 Flutter] GitHub로 버전관리하기, 사용법 (5) | 2024.09.12 |
---|---|
[플러터 Flutter] GitHub Access Token 발급방법 / 깃허브 토큰 발급방법 (0) | 2024.09.12 |
[플러터 Flutter] 상태관리 Provider, MultiProvider (0) | 2024.07.09 |
[플러터 Flutter] 객체지향(Object Oriented Programing,OOP)의 이해 (0) | 2024.07.05 |
[플러터 Flutter] 안드로이드 패키지명, iOS 번들아이디 찾기 Find Android Package Name, iOS BundleID (1) | 2024.06.16 |