Notice
Recent Posts
Recent Comments
Link
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

RealMan's development log

[Flutter] Kakao Login - 구현 본문

APP/Flutter

[Flutter] Kakao Login - 구현

참 진, 수컷 웅 2024. 5. 19. 22:50

 

 

[Flutter] Kakao Login - 세팅

Flutter에서 Kakao sdk를 사용해 소셜 로그인 구현을 해보겠습니다.이번 시간엔 구현 전에 필요한 세팅을 먼저 해보겠습니다.  - https://developers.kakao.com/ 에 접속합니다.  접속 후 상단 '내 어플리케

lovedev.tistory.com

 

Flutter 카카오 로그인 구현에 앞서 이전 포스팅에서 세팅을 먼저 해보았는데요?

이번 포스팅에선 실제로 로그인을 해보고 저번시간 세팅한 동의항목(닉네임, 이메일)을 가져오는것까지 해보겠습니다.

 

dependencies 추가

 

kakao_flutter_sdk_user | Flutter package

A flutter plugin for Kakao API, which supports Kakao login, KakaoTalk Share, User API, KakaoTalk API and Navi API.

pub.dev

 

우선 pubspec.yaml에 kakao_flutter_sdk_user를 추가해줍니다.

 

main.dart

import 'package:flutter/material.dart';
import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart';
import 'package:social_login/login_screen.dart';

void main() {
  KakaoSdk.init(nativeAppKey: '네이티브 앱 키');
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {


  @override
  Widget build(BuildContext context) {
    return const LoginScreen();
  }
}

 

main에 kakaosdk를 초기화해줍니다. 이때 키값은 저번시간에 세팅할때 사용한 네이티브 앱 키를 사용해주시면 되겠습니다.

 

social_platform.dart

enum SocialPlatform {
  kakao,
  none,
}

 

향후 타 플랫폼들 로그인도 구현할 예정이기때문에 enum으로 소셜 플랫폼을 만들어 두겠습니다. (none은 로그아웃때 사용할 예정입니다)

 

login_screen.dart

import 'dart:convert';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:kakao_flutter_sdk_user/kakao_flutter_sdk_user.dart';
import 'package:social_login/social_platform.dart';

class LoginScreen extends StatefulWidget {
  const LoginScreen({super.key});

  @override
  State<LoginScreen> createState() => _LoginScreen();
}

class _LoginScreen extends State<LoginScreen> {
  SocialPlatform _socialPlatform = SocialPlatform.none;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: _socialPlatform != SocialPlatform.none
            ? _logoutButton()
            : Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: [
                  _loginButton(
                    'kakao_logo',
                    signInWithKakao,
                  ),
                ],
              ),
      ),
    );
  }

  void signInWithKakao() async {
    try {
      bool isInstalled = await isKakaoTalkInstalled();

      OAuthToken token =
          isInstalled ? await UserApi.instance.loginWithKakaoTalk() : await UserApi.instance.loginWithKakaoAccount();

      print(token);

      final url = Uri.https('kapi.kakao.com', '/v2/user/me');

      final response = await http.get(
        url,
        headers: {
          HttpHeaders.authorizationHeader: 'Bearer ${token.accessToken}'
        },
      );

      final profileInfo = json.decode(response.body);
      print(profileInfo.toString());

      setState(() {
        _socialPlatform = SocialPlatform.kakao;
      });
    } catch (error) {
      print('카카오톡으로 로그인 실패 $error');
    }
  }

  void signOut() async {
    switch (_socialPlatform) {
      case SocialPlatform.kakao:
        await UserApi.instance.logout();
        break;
      case SocialPlatform.none:
        break;
    }

    setState(() {
      _socialPlatform = SocialPlatform.none;
    });
  }

  Widget _loginButton(String path, VoidCallback onTap) {
    return Card(
      elevation: 5.0,
      shape: const CircleBorder(),
      clipBehavior: Clip.antiAlias,
      child: Ink.image(
        image: AssetImage('asset/image/$path.png'),
        width: 60,
        height: 60,
        child: InkWell(
          borderRadius: const BorderRadius.all(
            Radius.circular(35.0),
          ),
          onTap: onTap,
        ),
      ),
    );
  }

  Widget _logoutButton() {
    return ElevatedButton(
      onPressed: signOut,
      style: ButtonStyle(
        backgroundColor: MaterialStateProperty.all(
          const Color(0xff0165E1),
        ),
      ),
      child: const Text('로그아웃'),
    );
  }
}

 

전체 코드를 보고 설명을 해드리겠습니다.

 

- build

    _socialPlatform이 none이 아니면(즉, 카카오로 로그인이 된상태라면) 로그아웃 버튼을, 로그아웃 상태라면 카카오 로그인 버튼을 만듭니다.

 

 

_signInWithKakao

    먼저 isKakaoTalkInstalled()라는 메소드를 호출해 카카오톡이 해당 디바이스에 설치되어있는지 여부를 bool타입으로 반환합니다. 카카오톡이 설치되어 있다면 UserApi.instance.loginWithKakaoTalk()을 통해 카카오톡을 실행하여 로그인이 진행되고, 카카오톡이 설치되어있지 않다면 UserApi.instance.loginWithKakaoAccount()을 통해 웹으로 카카오계정 로그인을 진행하게 됩니다.

 

    로그인을 성공했다면 OAuthToken으로 accessToken을 받을수있고, 이 토큰값을 가지고 카카오서버에 요청하게되면 동의항목에 동의했던 유저정보를 가지고 올 수 있게됩니다.

 

    이후 setState로 social_platform의 상태를 카카오로그인상태로 바꿔줍니다.

 

 

_signOut

    향후 더 추가될 타플랫폼들을 대응하기위해 switch case문을 사용했고 UserApi.instance.logout()을 통해 로그아웃을 진행합니다. 로그아웃 이후에는 setState로 social_platform의 상태를 로그아웃상태로 바꿔줍니다.

 

 

_loginButton

 

    파라미터로 이미지 경로와 VoidCallBack을 받습니다.(VoidCallBack? 입력 인자가 없는 함수를 호출할 수 있는 타입). 이미지는 assets/image/kakao_logo.png 로 준비해두었습니다.

 

 

_logoutButton

 

    ElevatedButton으로 onPressed에 signOut 함수를 등록합니다.

'APP > Flutter' 카테고리의 다른 글

[Flutter] int to double  (0) 2024.05.23
[Flutter] Kakao Login - 세팅  (0) 2024.05.08
[Flutter] 앱아이콘(AppIcon) 적용하기  (0) 2024.05.05