Firebase를 이용하여 Sign In with Apple 사용하기
파이어베이스에서 애플 로그인을 사용해보자.
알림 : 2020.04.08 안드로이드 환경에서 애플 로그인을 실행하는 플러그인을 개발하여 내용 추가함
알림 : 2019.12.29 아직 안드로이드나 iOS 12 이하에서 애플 로그인을 쉽게 적용할 수 있는 플러그인이 개발되지 않았으므로, 관련 내용은 추후에 추가할 예정
선행 작업
이 글은
1. 파이어베이스에 프로젝트 생성
2. 파이어베이스에 Android, iOS 등록
3. 애플 개발자 페이지에서 애플 로그인 활성화
4. 파이어베이스 호스팅 활성화
위 프로세스 이후의 작업을 다루므로 앞의 프로세스를 진행하지 않았다면 아래 링크에서 먼저 모든 작업을 완료해야 한다.
1. 파이어베이스 프로젝트 생성
2. 파이어베이스 프로젝트에 Android, iOS 등록
3. 애플 개발자 페이지에서 애플 로그인 활성화
4. 파이어베이스 호스팅 활성화
작업 순서
1. Firebase Console에서 Sign In with Apple 활성화
2. Apple 개발자 페이지에서 도메인 및 Callback URL 등록
3. apple-developer-domain-association.txt 호스팅
4. Flutter 프로젝트에 패키지 추가하기
4-1. Xcode에서 Sign In with Apple 활성화
5. 인증 소스코드 구현
5-1. iOS에서 인증하기
5-2. Android에서 인증하기
Firebase Console에서 Sign In with Apple 활성화
파이어베이스 콘솔에서 "개발 >> Authentication >> 로그인 방법" 으로 들어와 목록에서 Apple을 활성화 한다.
그리고 아래에 표시된 URL을 복사한다.
서비스 ID나 OAuth 코드 흐름 구성은 애플 로그인을 iOS에서만 구현한다면 비워도 되지만, 안드로이드에서도 구현할 예정이라면 채워야 한다.
필요한 항목은 서비스 ID, Apple 팀 ID, 키 ID, 비공개 키다. 모두 Apple 개발자 페이지에서 찾을 수 있다.
Apple 팀 ID는 그냥 개발자 계정 프로필에 보이는걸 찾으면 된다.
서비스 ID는 "Identifiers >> Services IDs"에서 Identifier로 표시된 것이다.
키 ID와 비공개 키는 "Keys"에서 찾을 수 있다.
비공개 키는 한 번 다운로드하면 새로 다운받을 수 없는데, 만약 분실했다면 Key를 다시 만들어야 한다. 이전 글의 내용을 제대로 진행했다면 당신의 컴퓨터에 제대로 키 파일이 들어있을 것이다.
Apple 개발자 페이지에서 도메인 및 Callback URL 등록
이 작업은 Apple 개발자 페이지에 Sign In with Apple 설정이 미리 되어있어야 한다. 안되어있다면 위의 선행 작업 항목을 다시 읽고 오자.
애플 개발자 페이지에 접속하고 "Identifiers >> Services IDs"로 들어와서 이전에 만들어두었던 서비스 아이디를 찾는다.
아래 Configure 버튼 클릭
애플 로그인 인증 절차에 사용할 도메인과 Callback URL(Return URLs)을 등록하는 화면이 나온다.
아까 파이어베이스에서 복사해두었던 URL을 채워넣고 Save 버튼 클릭
apple-developer-domain-association.txt 호스팅
Configure 버튼을 다시 클릭한다.
Download, Verify 버튼이 새로 생겼다. Download 버튼을 클릭하여 apple-developer-domain-association.txt를 다운로드 한다.
도메인 소유권을 확인하기 위해, 이 파일을 파이어베이스ID.firebaseapp.com 에서 호스팅 해주어야 한다.
파이어베이스 호스팅 설정을 하지 않았다면 스크롤을 올려서 선행 작업 항목을 읽고 오자.
파이어베이스ID.firebaseapp.com/.well-known/apple-developer-domain-association.txt로 접속했을 때 파일이 호스팅 되도록 위 처럼 디렉토리를 구성한다.
그리고 CLI 명령어를 이용해서 배포한다.
해당 URL로 접근했을 때 파일의 내용이 보인다면 호스팅 성공
다시 애플 페이지로 돌아와서 Verify 버튼을 클릭
초록색 V마크가 생겼으면 등록한 도메인에 대한 소유권 확인이 완료된 것이다.
이제 애플 로그인을 시도하면 OAuth 과정을 위 도메인을 통해서 진행하게 된다.
여기까지가 애플 로그인을 활성화 하기 위한 준비 과정이다.
Flutter 프로젝트에 패키지 추가하기
// pubspec.yaml
dependencies:
firebase_auth: ^0.15.3
apple_sign_in: ^0.1.0
apple_sign_in_firebase:
path: plugins/apple_sign_in_firebase
pubspec.yaml에 firebase_auth와 apple_sign_in(ios), apple_sign_in_firebase(android) 패키지를 설치한다.
플러터 안드로이드 환경에서 애플 로그인을 수행하는 플러그인이 하나도 없었으나, 네이티브 안드로이드 파이어베이스에서는 애플 로그인이 제대로 작동하는 것을 확인했기 때문에 플러터에서 해당 네이티브 코드를 호출하도록 wrapping 정도만 해준 apple_sign_in_firebase 패키지를 본인이 직접 개발하였다. (후에 정식 라이브러리가 나온다면 그걸 쓰십시오...)
pub.dev에는 업로드 하지 않았으므로 이 링크로 들어가서 플러그인을 다운받고 직접 프로젝트 폴더 안에 추가하자.
plugins라는 디렉토리에 넣어줄 것이다.
(※ firebase_auth 패키지는 0.15.3 이상부터 애플 로그인을 지원한다.)
Xcode에서 Sign In with Apple 활성화
이 항목은 iOS만 해당됨.
Xcode로 프로젝트를 열고 Signing & Capabilities 탭에서 +Capability 버튼 클릭
Sign In with Apple 선택
위와 같이 추가되면 성공
인증 소스코드 구현
iOS에서 인증하기
애플 로그인은 iOS 13 이상에서만 지원한다.
선요약을 하자면, 네이티브 애플 로그인 SDK의 결과값을 파이어베이스에 전달하여 인증하는 방식이다.
// call iOS native SDK
AuthorizationRequest authorizationRequest = AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName]);
AuthorizationResult authorizationResult = await AppleSignIn.performRequests([authorizationRequest]);
로그인 성공 시 받아오고 싶은 정보(메일, 이름)를 scope로 지정하고 인증 요청을 한다.
그럼 위와 같은 UI가 나타난다. 대충 애플 로그인에 대해 소개하는 화면인듯... Continue 터치.
iCloud에 연동된 애플 계정을 보여준다. iCloud에 연동된 애플 계정으로 로그인을 바로 할 수 있도록 하는게 애플 로그인이다.
iCloud에 애플 계정을 연동하지 않았거나 이중 인증 기능이 꺼져있는 계정은 애플 로그인을 이용할 수 없으므로 주의.
로그인 할 때 앱에 넘겨줄 이메일을 선택할 수 있는데 하나는 진짜 이메일이고, 나머지 하나는 우회 이메일이다.
우회 이메일은 자신의 진짜 이메일을 제공하고 싶지 않을 때 선택하면 된다.
우회 이메일 주소로 메일을 보내면 진짜 이메일로 재전달(relay) 되기 때문에 메일 서비스를 이용할 때는 아무런 지장이 없다.
만약 내 진짜 이메일이 aaa@gmail.com이면 우회 이메일은 dfsulgher@privaterelay.appleid.com 처럼 랜덤으로 생성되고,
dfsulgher@privaterelay.appleid.com에 메일을 보내면 진짜 주소인 aaa@gmail.com로 메일이 도착하는 식이다.
다시 한 번 Continue 버튼 터치
Face ID를 지원하는 기기에서는 Face ID로 인증하는 UI가 나타나고, 지원하지 않는 기기에서는 비밀번호로 인증하는 UI가 나타난다.
AppleIdCredential appleCredential = authorizationResult.credential;
OAuthProvider provider = new OAuthProvider(providerId: "apple.com");
AuthCredential credential = provider.getCredential(
idToken: String.fromCharCodes(appleCredential.identityToken),
accessToken: String.fromCharCodes(appleCredential.authorizationCode),
);
애플에서 인증한 결과를 appleCredential에 담아준다.
그리고 파이어베이스에서 인증을 한 번 더 처리하도록 provider를 할당하고 파이어베이스용 credential를 만든다.
FirebaseAuth auth = FirebaseAuth.instance;
AuthResult authResult = await auth.signInWithCredential(credential);
// 인증에 성공한 유저 정보
FirebaseUser user = authResult.user;
그리고 signInWithCredential 함수를 이용해 파이어베이스에서 인증을 처리하도록 구현한다.
유저 정보가 성공적으로 로딩된다면 구현에 성공한 것이다.
AuthorizationRequest authorizationRequest = AppleIdRequest(requestedScopes: [Scope.email, Scope.fullName]);
AuthorizationResult authorizationResult = await AppleSignIn.performRequests([authorizationRequest]);
AppleIdCredential appleCredential = authorizationResult.credential;
OAuthProvider provider = new OAuthProvider(providerId: "apple.com");
AuthCredential credential = provider.getCredential(
idToken: String.fromCharCodes(appleCredential.identityToken),
accessToken: String.fromCharCodes(appleCredential.authorizationCode),
);
FirebaseAuth auth = FirebaseAuth.instance;
AuthResult authResult = await auth.signInWithCredential(credential);
// 인증에 성공한 유저 정보
FirebaseUser user = authResult.user;
전체 소스코드는 위와 같다.
Android에서 인증하기
네이티브 파이어베이스 코드를 실행할 것이므로 파이어베이스 설정이 올바르게 되있어야 한다.
// call android native firebase
final Map appleCredential = await AppleSignInFirebase.signIn();
위 코드를 통해서 네이티브 파이어베이스 애플로그인을 실행시키고 애플에서 발급한 credential을 받아온다.
이 시점에서 내부적으로 인증을 한 번 수행하므로 파이어베이스에 계정이 생성된다.
OAuthProvider provider = new OAuthProvider(providerId: "apple.com");
AuthCredential credential = provider.getCredential(
idToken: appleCredential['idToken'],
accessToken: appleCredential['accessToken'],
);
그리고 파이어베이스에서 인증을 한 번 더 처리하도록 provider를 할당하고 파이어베이스용 credential를 만든다. 나머지 로직은 iOS와 동일하다.
FirebaseAuth auth = FirebaseAuth.instance;
AuthResult authResult = await auth.signInWithCredential(credential);
// 인증에 성공한 유저 정보
FirebaseUser user = authResult.user;
그리고 signInWithCredential 함수를 이용해 파이어베이스에서 인증을 처리하도록 구현한다.
유저 정보가 성공적으로 로딩된다면 구현에 성공한 것이다.
final Map appleCredential = await AppleSignInFirebase.signIn();
OAuthProvider provider = new OAuthProvider(providerId: "apple.com");
AuthCredential credential = provider.getCredential(
idToken: String.fromCharCodes(credential['idToken']),
accessToken: String.fromCharCodes(credential['accessToken']),
);
FirebaseAuth auth = FirebaseAuth.instance;
AuthResult authResult = await auth.signInWithCredential(credential);
// 인증에 성공한 유저 정보
FirebaseUser user = authResult.user;
전체 소스코드는 위와 같다.
이후에 파이어베이스 페이지에서 확인해보면 애플 로그인을 사용한 계정 목록을 볼 수 있다.
위는 우회 이메일로 가입한 유저고, 아래는 진짜 이메일로 가입한 유저이다.
댓글