서버없이 Flutter로 네이버 로그인 하기 - iOS

송민경's avatar
Aug 24, 2024
서버없이 Flutter로 네이버 로그인 하기 - iOS

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

flutter_naver_login: ^1.8.0
 

2. iOS 개발을 위한 추가 라이브러리 설치하기

  • CocoaPods : iOS 및 macOS 개발에서 라이브러리를 쉽게 관리할 수 있는 의존성 관리 도구
    • Podfile이라는 파일을 통해 프로젝트에 필요한 라이브러리와 버전을 정의
      • 프로젝트의 루트 디렉토리에 위치
      • 프로젝트에서 사용할 CocoaPods 라이브러리 및 버전을 지정
  • pod install : Podfile에 정의된 라이브러리와 그 의존성들을 실제로 다운로드하고 설치
    • CocoaPods는 필요한 라이브러리를 Pods 디렉토리 아래에 설치
    • Xcode 프로젝트 파일 (.xcodeproj)을 업데이트하여 설치된 라이브러리와 연동
iOS 프로젝트에서 CocoaPods를 사용하여 외부 라이브러리나 의존성을 설치하는 명령어 pod install
 

3. 로그인하고 애플리케이션 등록하기

notion image
notion image
  • 앱을 앱 스토어에 배포한 경우가 아니라면 안드로이드는 앱패키지 명만 입력해도 됨
    • 패키지명 확인하기
위치 : android/app/src/main/AndroidManifest.xml
notion image
  • iOS는 URL스킴, 로그인 후 돌아온 주소, 넣어주고 싶은 이름으로 넣어주면 됨
notion image
 

4. 클라이언트 id, 클라이언트 secret 확인하기

notion image
 

5. AppDelegate 설정하기

  • 파일 위치 : ios/Runner/AppDelegate.swift
  • 로그인 방법에 따른 활성화하기
네이버 앱으로 인증하는 방식 활성화 [[NaverThirdPartyLoginConnection getSharedInstance] setIsNaverAppOauthEnable:YES]; SafariViewContoller에서 인증하는 방식 활성화 [[NaverThirdPartyLoginConnection getSharedInstance] setIsInAppOauthEnable:YES];
  • 상수값을 정의해서 설정하는 방법
    • 상수를 설정하는 파일 : NaverThirdPartyConstantsForApp.h
    • 상숫값을 개발하고 있는 애플리케이션에 맞는 값으로 변경해줘야 함
    • 값을 상수에 저장 #define kUrlSampleAppUrlScheme @"thirdparty20samplegame" // 콜백을 받을 URL Scheme #define kConsumerKey @"jyvqXeaVOVmV" // 애플리케이션에서 사용하는 클라이언트 아이디 #define kConsumerSecret @"527300A0_COq1_XV33cf" // 애플리케이션에서 사용하는 클라이언트 시크릿 #define kServiceAppName @"네이버 로그인하기" // 애플리케이션 이름
    • 애플리키션의 값을 상수에 저장한 값을 불러서 사용
      • #import <NaverThirdPartyLogin/NaverThirdPartyLogin.h> - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { ... 생략 ... NaverThirdPartyLoginConnection *thirdConn = [NaverThirdPartyLoginConnection getSharedInstance]; [thirdConn setServiceUrlScheme:kServiceAppUrlScheme]; [thirdConn setConsumerKey:kConsumerKey]; [thirdConn setConsumerSecret:kConsumerSecret]; [thirdConn setAppName:kServiceAppName]; ... 생략 ... return YES; } thirdConn?.serviceUrlScheme = kServiceAppUrlScheme thirdConn?.setConsumerKey = kConsumerKey thirdConn?.setConsumerSecret = kConsumerSecret thirdConn?.setAppName = kServiceAppName
      • 코드 적용하기
      • import Flutter import UIKit // Naver Third Party Login 관련 상수 정의 let kServiceAppUrlScheme = "YOUR_SERVICE_URL_SCHEME" let kConsumerKey = "YOUR_CONSUMER_KEY" let kConsumerSecret = "YOUR_CONSUMER_SECRET" let kServiceAppName = "Your_App_Name" @main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) // Naver Third Party Login 초기화 let thirdConn = NaverThirdPartyLoginConnection.getSharedInstance() thirdConn?.isNaverOauthEnable = true thirdConn?.isInAppOauthEnable = true // 서비스 파라미터 설정 thirdConn?.setServiceUrlScheme(kServiceAppUrlScheme) thirdConn?.setConsumerKey(kConsumerKey) thirdConn?.setConsumerSecret(kConsumerSecret) thirdConn?.setAppName(kServiceAppName) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
      • 상수값 확인하기
      • notion image
  • 상수값 적용없이 바로 입력하기
import Flutter import UIKit @main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) // Naver Third Party Login 초기화 let thirdConn = NaverThirdPartyLoginConnection.getSharedInstance() thirdConn?.isNaverOauthEnable = true thirdConn?.isInAppOauthEnable = true // 서비스 파라미터 설정 thirdConn?.serviceUrlScheme = "YOUR_SERVICE_URL_SCHEME" thirdConn?.consumerKey = "YOUR_CONSUMER_KEY" thirdConn?.consumerSecret = "YOUR_CONSUMER_SECRET" thirdConn?.serviceAppName = "Your_App_Name" return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }
  • 메서드 추가하기
override func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { var applicationResult = false if (!applicationResult) { applicationResult = NaverThirdPartyLoginConnection.getSharedInstance().application(app, open: url, options: options) } // if you use other application url process, please add code here. if (!applicationResult) { applicationResult = super.application(app, open: url, options: options) } return applicationResult }
  • 코드 적용하기
import Flutter import UIKit @main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GeneratedPluginRegistrant.register(with: self) // Naver Third Party Login 초기화 let thirdConn = NaverThirdPartyLoginConnection.getSharedInstance() thirdConn?.isNaverOauthEnable = true thirdConn?.isInAppOauthEnable = true // 서비스 파라미터 설정 thirdConn?.serviceUrlScheme = "YOUR_SERVICE_URL_SCHEME" thirdConn?.consumerKey = "YOUR_CONSUMER_KEY" thirdConn?.consumerSecret = "YOUR_CONSUMER_SECRET" thirdConn?.serviceAppName = "Your_App_Name" return super.application(application, didFinishLaunchingWithOptions: launchOptions) } override func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { var applicationResult = false if (!applicationResult) { applicationResult = NaverThirdPartyLoginConnection.getSharedInstance().application(app, open: url, options: options) } // if you use other application url process, please add code here. if (!applicationResult) { applicationResult = super.application(app, open: url, options: options) } return applicationResult } }
 

7. Info.plist 설정하기

  • 파일 위치 : ios/Runner/Info.plist
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleTypeRole</key> <string>Editor</string> <key>CFBundleURLSchemes</key> <array> <string>[UrlScheme]</string> </array> </dict> </array>
<key>LSApplicationQueriesSchemes</key> <array> <string>naversearchapp</string> <string>naversearchthirdlogin</string> </array> <key>naverServiceAppUrlScheme</key> <string>[UrlScheme]</string> <key>naverConsumerKey</key> <string>[ConsumerKey]</string> <key>naverConsumerSecret</key> <string>[ConsumerSecret]</string> <key>naverServiceAppName</key> <string>[ServiceAppName]</string>
<!-- http allows configurations --> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> <key>NSExceptionDomains</key> <dict> <key>naver.com</key> <dict> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSIncludesSubdomains</key> <true/> </dict> <key>naver.net</key> <dict> <key>NSExceptionRequiresForwardSecrecy</key> <false/> <key>NSIncludesSubdomains</key> <true/> </dict> </dict> </dict>
 

8. 로그인 구현하기

  • 예제코드
NaverLoginResult res = await FlutterNaverLogin.logIn(); final NaverLoginResult result = await FlutterNaverLogin.logIn(); NaverAccessToken res = await FlutterNaverLogin.currentAccessToken; setState(() { accesToken = res.accessToken; tokenType = res.tokenType; });
 

9. main.dart 설정하기

  • 카카오 로그인과 달리 네이버 로그인은 초기화할 필요가 없음
import 'package:flutter/material.dart'; import 'package:flutter_game_test/login_page.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.white), useMaterial3: true, ), home: LoginPage(), ); } }
 

10. naver_login_service.dart 만들기

  • 굳이 따로 안 만들어도 됨
import 'package:flutter_naver_login/flutter_naver_login.dart'; class NaverLoginService { Future<void> naverLogin() async { try { // 네이버 로그인 시도 final NaverLoginResult result = await FlutterNaverLogin.logIn(); // 현재 액세스 토큰 가져오기 final NaverAccessToken res = await FlutterNaverLogin.currentAccessToken; // 액세스 토큰 및 토큰 타입 출력 print("======accesToken: ${res.accessToken}"); print("======tokenType: ${res.tokenType}"); } catch (e) { // 로그인 과정에서 오류 발생 시 처리 print("로그인 중 오류 발생: $e"); } } }
 

11. login_page.dart 만들기

  • 이미지 다운받아 네이버 로그인 버튼 만들기
notion image
notion image
notion image
notion image
import 'package:flutter/material.dart'; import 'naver_login_service.dart'; class LoginPage extends StatelessWidget { final NaverLoginService _naverService = NaverLoginService(); // NaverLoginService 인스턴스 생성 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Login'), ), body: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ // Naver 로그인 버튼을 이미지로 구현 InkWell( onTap: () async { await _naverService.naverLogin(); // 로그인 처리 }, child: Image.asset( 'assets/images/btnG_완성형.png', // 이미지 경로 width: 200, // 이미지 너비 (필요에 따라 조정) ), ), ], ), ), ); } }
notion image
  • 직접 네이버 로그인 버튼 만들기
import 'package:flutter/material.dart'; import 'naver_login_service.dart'; class LoginPage extends StatelessWidget { final NaverLoginService _naverService = NaverLoginService(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Login'), ), body: Center( child: Column( mainAxisSize: MainAxisSize.min, children: [ // Naver 로그인 버튼 ElevatedButton( onPressed: () async { await _naverService.naverLogin(); // 로그인 처리 }, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: Colors.green, // 초록색 배경 설정 shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ SizedBox(width: 10), Text( 'Naver 로그인', style: TextStyle(fontSize: 16), ), SizedBox(width: 10), ], ), ), ], ), ), ); } }
notion image
 

12. 로그아웃

  • 코드아웃 코드 적용하기
Future<void> naverLogout() async { try { // 네이버 로그아웃 시도 await FlutterNaverLogin.logOut(); print("로그아웃 성공"); } catch (e) { // 로그아웃 과정에서 오류 발생 시 처리 print("로그아웃 중 오류 발생: $e"); } }
  • 버튼 만들기
ElevatedButton( onPressed: () async { await _naverService.naverLogout(); // 로그아웃 처리 }, style: ElevatedButton.styleFrom( foregroundColor: Colors.white, backgroundColor: Color(0xFF03C75A), // 네이버의 쨍한 초록색 fixedSize: Size(200, 50), // 버튼의 너비를 200으로 설정 (높이는 50으로 설정) shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(0), // 모서리를 각지게 설정 ), ), child: Text( '네이버 로그아웃', style: TextStyle(fontSize: 18), // 텍스트 크기를 18로 설정 ), ),
Share article

vosw1