๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿพ ๊ฐœ๋ฐœ ๐Ÿพ/Flutter

[Flutter] ๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ (iOS/Android)

๋ฐ˜์‘ํ˜•

1.  naver ๊ฐœ๋ฐœ์ž ์„ค์ •

https://developers.naver.com/apps/#/register?api=nvlogin 

 

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - NAVER Developers

 

developers.naver.com

 

- ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋ก

- ์•ˆ๋“œ๋กœ์ด๋“œ ์„ค์ •

๋‹ค์šด๋กœ๋“œ url : https://play.google.com/store/ (์•„์ง ๋“ฑ๋กํ•œ url์ด ์—†์œผ๋ฏ€๋กœ ์šฐ์„  ์ด๋ ‡๊ฒŒ ์ž…๋ ฅํ•ด์ค๋‹ˆ๋‹ค.)

์•ฑ ํŒจํ‚ค์ง€ ์ด๋ฆ„ : (android/app/src/main/AndroidManifest.xml ์—์„œ ํŒจํ‚ค์ง€ ๋ช…์„ ๊ฐ€์ ธ์™€ ๋ณต๋ถ™ํ•ฉ๋‹ˆ๋‹ค.)

 

- iOS ์„ค์ •

๋‹ค์šด๋กœ๋“œ url : https://www.apple.com/kr/app-store/ (์ด๊ฒƒ๋„ ์•„์ง ์—†์Œ์œผ๋กœ ์ผ๋‹จ ์ž…๋ ฅํ•ด์ค๋‹ˆ๋‹ค.)

URL Scheme : ๋กœ๊ทธ์ธ ํ›„ Callback์„ ์ „๋‹ฌ๋ฐ›์„ URL-Scheme๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.

 

 

ํ•„์š”ํ•œ ์ •๋ณด๋“ค์ด๋‹ˆ ๊ธฐ์–ตํ•ด์ค๋‹ˆ๋‹ค.

- Client Name (์„ค์ •ํ•œ ์•ฑ ์ด๋ฆ„) : ${app_name}

- Client ID : ${clientId}

- Client Secret : ${client_secret} 

- URL Scheme (iOS) : ${url_scheme}

 

 

 

 

 

 

 

 

 

 

2. ํŒจํ‚ค์ง€ ์„ค์น˜

flutter_naver_login: ^1.6.0

https://pub.dev/packages/flutter_naver_login

 

flutter_naver_login | Flutter Package

A Flutter plugin for using the native Naver Login SDKs on Android and iOS.

pub.dev

 

 

 

 

 

 

 

 

 

 

3 . ์•ˆ๋“œ๋กœ์ด๋“œ ์„ค์ •

android/app/src/main/res/values/strings.xml

์œ„์—์„œ ๊ธฐ์–ตํ•ด๋‘” ์ •๋ณด๋“ค์„ ์ž…๋ ฅํ•ด์ค๋‹ˆ๋‹ค.

<?xml version="1.0" encoding="utf-8"?>
<resources>
	... 

    <!-- naver login -->
    <string name="client_id">${client_id}</string>
    <string name="client_secret">${client_secret}</string>
    <string name="client_name">${app_name}</string>
    
</resources>

android/app/src/main/AndroidManifest.xml

<application
...
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
            
        <!-- ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ด์ค๋‹ˆ๋‹ค. -->    
        <meta-data
            android:name="com.naver.sdk.clientId"
            android:value="@string/client_id" />
        <meta-data
            android:name="com.naver.sdk.clientSecret"
            android:value="@string/client_secret" />
        <meta-data
            android:name="com.naver.sdk.clientName"
            android:value="@string/client_name" />
...

 

 

 

 

 

 

 

 

 

4 . iOS ์„ค์ •

info.plist ์„ค์ •์— ์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

์œ„์—์„œ ๊ธฐ์–ตํ•ด๋‘” ์ •๋ณด๋“ค์„ ์ž…๋ ฅํ•ด์ค๋‹ˆ๋‹ค.

${...} ์ธ ๋ถ€๋ถ„ ๋“ค๋งŒ ๋ฐ”๊พธ์–ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

<plist version="1.0">
		...
        <key>CFBundleURLTypes</key>
        <array>
            <dict>
                <key>CFBundleTypeRole</key>
                <string>Editor</string>
                <key>CFBundleURLSchemes</key>
                <array>
                    <string>${url_scheme}</string>
                </array>
            </dict>
        </array>

        <key>LSApplicationQueriesSchemes</key>
        <array>
            <string>naversearchapp</string>
            <string>naversearchthirdlogin</string>
        </array>
        <key>naverServiceAppUrlScheme</key>
        <string>${url_scheme}</string>
        <key>naverConsumerKey</key>
        <string>${client_id}</string>
        <key>naverConsumerSecret</key>
        <string>${client_secret}</string>
        <key>naverServiceAppName</key>
        <string>${app_name}</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>
        
        ...
    </dict>
</plist>

 

ios/Runner/AppDelegate.swift

/// ... ์™€ /// ๋กœ ๋‘˜๋Ÿฌ์Œ“์ธ ๋ถ€๋ถ„์˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

import UIKit
import Flutter

/// naver ๋กœ๊ทธ์ธ import ์ถ”๊ฐ€
import NaverThirdPartyLogin
///



@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    
    
    /// ์•„๋ž˜์˜ ์ฝ”๋“œ ์ถ”๊ฐ€
    override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : 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
    }
    /// 
    
}

 

 

 

 

 

 

 

 

5. ์ฝ”๋“œ ์ž‘์„ฑ

import 'package:flutter/material.dart';
import 'package:flutter_naver_login/flutter_naver_login.dart';

class NaverLoginView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ')),
      body: _buildBody(context),
    );
  }

  Widget _buildBody(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(24),
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.max,
        children: [
          _loginBtn(context),
          Padding(padding: EdgeInsets.all(8)),
          _logoutBtn(context)
        ],
      ),
    );
  }


  // ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ
  Widget _loginBtn(BuildContext context) {
    return GestureDetector(
      onTap: () {
        _tapLoginBtn(context);
      },
      child: Container(
        decoration: const BoxDecoration(
          color: Color.fromRGBO(3, 199, 90, 1),
          borderRadius: BorderRadius.all(Radius.circular(8)),
        ),
        padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 24),
        child: Row(
          children: [
            SizedBox(
                width: 40,
                child: Image.asset('assets/auth/naver_logo_icon.png')),
            const Padding(padding: EdgeInsets.all(4)),
            const Text(
              '๋„ค์ด๋ฒ„๋กœ ๋กœ๊ทธ์ธํ•˜๊ธฐ',
              style: TextStyle(
                  fontSize: 16, color: Color.fromARGB(255, 25, 22, 22)),
            ),
          ],
        ),
      ),
    );
  }


  // ๋กœ๊ทธ์•„์›ƒ ๋ฒ„ํŠผ
  Widget _logoutBtn(BuildContext context) {
    return TextButton(
      onPressed: () {
        _tapLogoutBtn(context);
      },
      child: Text('๋กœ๊ทธ์•„์›ƒ'),
    );
  }


  // ๋กœ๊ทธ์ธ
  void _tapLoginBtn(BuildContext context) async {
    NaverLoginResult loginResult = await FlutterNaverLogin.logIn();

    print(loginResult.account.email);
    print(loginResult.account.birthday);
    print(loginResult.account.nickname);
    print(loginResult.account.mobile);

    NaverAccessToken accessToken = await FlutterNaverLogin.currentAccessToken;
    print(accessToken.accessToken);
  }


  // ๋กœ๊ทธ์•„์›ƒ
  void _tapLogoutBtn(BuildContext context) async {
    NaverLoginResult loginResult = await FlutterNaverLogin.logOut();
    print(loginResult.account.email);
    print(loginResult.account.birthday);
    print(loginResult.account.nickname);
    print(loginResult.account.mobile);
  }
}

 

 

 

 

 

 

 

 

 

6. ๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ๋””์ž์ธ ๊ฐ€์ด๋“œ

https://developers.naver.com/docs/login/bi/bi.md

 

๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ์‚ฌ์šฉ ๊ฐ€์ด๋“œ - LOGIN

๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋„ค์ด๋ฒ„ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํ™ฉ์— ๋งž๊ฒŒ ๋ฒ„ํŠผ ์ด๋ฏธ์ง€์˜ ๋””์ž์ธ์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋„ค์ด๋ฒ„ ๊ณ ์œ ์˜ ์•„์ด๋ด

developers.naver.com

 

 

 

 

 

7.  kakao && naver ์‚ฌ์šฉ ์‹œ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ์ 

https://velog.io/@tygerhwang/FLUTTER-Kakao-Login-Issue

 

[FLUTTER] Kakao Login Issue

Kakao Login Issue

velog.io

 

๋ฐ˜์‘ํ˜•