Flutter/Social Login

[Flutter] Apple Login ② - 구현

찌김이 2022. 8. 27. 06:00
728x90
반응형
 

[Flutter] Apple Login ① - 준비

마지막으로 구현할 소셜로그인은 애플 로그인 입니다. 애플 로그인을 구현하기 위해서는 개발자 계정에 가입되어있어야하고 비용은 1년에 13만원 입니다. ㅠㅠ Apple Developer There’s never been a bette

dalgoodori.tistory.com

 

이전 포스팅에서 애플 로그인을 위한 모든 셋팅을 완료하였습니다.

이번 포스팅에서는 애플 로그인을 구현하고 유저의 정보를 가져오는 것 까지 구현해보겠습니다.

 

pubspec.yaml

 

sign_in_with_apple | Flutter Package

Flutter bridge to initiate Sign in with Apple (on iOS, macOS, and Android). Includes support for keychain entries as well as signing in with an Apple ID.

pub.dev

dependencies:
  sign_in_with_apple: ^4.1.0

 

 

login_platform.dart

  • 로그인을 구현할 플랫폼들을 enum 으로 한개 만들어 둡니다.

 

enum LoginPlatform {
  facebook,
  google,
  kakao,
  naver,
  apple,
  none, // logout
}

 

sample_screen.dart

  • 로고 버튼을 눌러 로그인을 실행하고 로그아웃 버튼으로 로그아웃을 처리하는 화면입니다.
  • StatefulWidget 으로 만들고 현재 로그인한 플랫폼을 저장할 변수를 선언합니다.

 

LoginPlatform _loginPlatform = LoginPlatform.none;

 

 

로그인 처리 

  • 모든 셋팅을 정상적으로 완료하였다면 아래의 코드로 로그인이 진행됩니다.
  • clientId 값은 Servide ID 값을 넣어주시고 이전 포스팅에서 설정했던 redirectUri 를 넣어주세요. 

 

final AuthorizationCredentialAppleID credential = await SignInWithApple.getAppleIDCredential(
        scopes: [
          AppleIDAuthorizationScopes.email,
          AppleIDAuthorizationScopes.fullName,
        ],
        webAuthenticationOptions: WebAuthenticationOptions(
          clientId: "Apple Developer 에서 설정한 Service ID",
          redirectUri: Uri.parse(
            "Apple Developer 에서 설정한 redirectUri",
          ),
        ),
      );

 

 

  • 로그인을 성공하면 AuthorizationCredentialAppleID 값을 받을 수 있고 별도의 통신 없이 로그인 유저 정보를 받을 수 있습니다.
  • 이름과 이메일 정보는 앱에 처음 로그인 했을 때만 받아올 수 있습니다.

 

const AuthorizationCredentialAppleID({
  @required this.userIdentifier,
  @required this.givenName,
  @required this.familyName,
  required this.authorizationCode,
  @required this.email,
  @required this.identityToken,
  @required this.state,
});

 

 

  • 로그인을 처리하는 함수 이며 로그인 성공시 loginPlatform 을 apple 로 갱신시켜줍니다.

 

void signInWithApple() async {
  try {
    final AuthorizationCredentialAppleID credential =
        await SignInWithApple.getAppleIDCredential(
      scopes: [
        AppleIDAuthorizationScopes.email,
        AppleIDAuthorizationScopes.fullName,
      ],
      webAuthenticationOptions: WebAuthenticationOptions(
        clientId: "Apple Developer 에서 설정한 Service ID",
        redirectUri: Uri.parse(
          "Apple Developer 에서 설정한 redirectUri",
        ),
      ),
    );

    print('credential.state = $credential');
    print('credential.state = ${credential.email}');
    print('credential.state = ${credential.userIdentifier}');

    setState(() {
      _loginPlatform = LoginPlatform.apple;
    });
  } catch (error) {
    print('error = $error');
  }
}

 

 

로그아웃 처리

  • 애플 로그인은 다른 소셜 로그인 처럼 로그아웃 처리가 없고 사용자가 직접 앱과 계정의 연결을 끊어야 합니다.
  • 현재 loginPlatform 의 값을 none 으로만 갱신시켜줍니다.
void signOut() async {
  switch (_loginPlatform) {
    case LoginPlatform.facebook:
      break;
    case LoginPlatform.google:
      break;
    case LoginPlatform.kakao:
      break;
    case LoginPlatform.naver:
      break;
    default:
      break;
  }

  setState(() {
    _loginPlatform = LoginPlatform.none;
  });
}

 

 

로그인 버튼

  • onPressed 나 onTap 이 있는 아무 위젯이나 사용해도 되지만 그렇게하면 기분이 나지 않으니 버튼을 구현해봅시다.
  • 로고는 아래 링크에서 다운받으시면 됩니다.

 

 

Apple Design Resources

Design apps quickly by using Sketch and Photoshop templates, plug-ins, and preconfigured UI elements.

developer.apple.com

 

 

 

  • 프로젝트에서 asset 폴더와 그 안에 image 폴더를 만들고 다운받은 로고를 넣어줍니다.

 

  • pubspec.yaml 에 assets 를 추가해주세요.
flutter:
  assets:
    - asset/image/

 

 

  • 버튼에 그림자 효과를 주기위해 Card 위젯을 사용했습니다.
  • 버튼에 ripple 효과를 주기위해 Card 위젯 자식으로 Ink 위젯을 사용했습니다.
  • 그리고 onTap 사용을 위해 InkWell 위젯을 사용했습니다.
  • 이미지 경로는 path 부분을 빼고 모두 공통으로 처리할 것이기 때문에 이미지의 이름만 path 로 받습니다.
  • VoidCallback 을 통해 로그인 처리를 하는 함수를 받습니다.

 

  Widget _loginButton(String path, VoidCallback onTap) {
    return Card(
      elevation: 18.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('로그아웃'),
    );
  }

 

 

 

전체 코드

sample_screen.dart

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

import 'package:flutter/material.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
import 'package:social_login_app/login_platform.dart';

class SampleScreen extends StatefulWidget {
  const SampleScreen({Key? key}) : super(key: key);

  @override
  State<SampleScreen> createState() => _SampleScreenState();
}

class _SampleScreenState extends State<SampleScreen> {
  LoginPlatform _loginPlatform = LoginPlatform.none;

  void signInWithApple() async {
    try {
      final AuthorizationCredentialAppleID credential =
          await SignInWithApple.getAppleIDCredential(
        scopes: [
          AppleIDAuthorizationScopes.email,
          AppleIDAuthorizationScopes.fullName,
        ],
        webAuthenticationOptions: WebAuthenticationOptions(
          clientId: "Apple Developer 에서 설정한 Service ID",
          redirectUri: Uri.parse(
            "Apple Developer 에서 설정한 redirectUri",
          ),
        ),
      );

      print('credential.state = $credential');
      print('credential.state = ${credential.email}');
      print('credential.state = ${credential.userIdentifier}');

      setState(() {
        _loginPlatform = LoginPlatform.apple;
      });
    } catch (error) {
      print('error = $error');
    }
  }

  void signOut() async {
    switch (_loginPlatform) {
      case LoginPlatform.facebook:
        break;
      case LoginPlatform.google:
        break;
      case LoginPlatform.kakao:
        break;
      case LoginPlatform.naver:
        break;
      default:
        break;
    }

    setState(() {
      _loginPlatform = LoginPlatform.none;
    });
  }

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

  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('로그아웃'),
    );
  }
}

 

login_platform.dart

enum LoginPlatform {
  facebook,
  google,
  kakao,
  naver,
  apple,
  none,
}
 
 

 

애플 로그인 뿐만 아니라 다른 소셜 로그인 구현도 포스팅 해놓았습니다!!  

 

코딩전사의 기록

 

dalgoodori.tistory.com

 

 

 

 

728x90
반응형

'Flutter > Social Login' 카테고리의 다른 글

[Flutter] Apple Login ① - 준비  (1) 2022.08.26
[Flutter] Naver Login ② - 구현  (5) 2022.08.25
[Flutter] Naver Login ① - 준비  (0) 2022.08.24
[Flutter] Kakao Login ② - 구현  (1) 2022.08.23
[Flutter] Kakao Login ① - 준비  (3) 2022.08.22