이번 글은 Flutter 프로젝트에서 파이어베이스 인증을 사용하여 구글 로그인을 해보겠습니다
Firebase Authentication
Firebase Authentication을 사용하면 서버 측 코드 없이 다양한 제공업체의 사용자를 인증하고 관리할 수 있습니다.
그러면 Flutter에서 firebase을 사용하여 구글 계정 인증하기를 해보겠습니다!
프로젝트에서 빌드-> Authentication 메뉴를 클릭하고 시작하기 버튼을 클릭합니다
그러면 로그인 제공 업체가 보여지는데 이 중 Google로 진행해보겠습니다
구글을 선택하면 위와 같은 화면이 나타납니다
프로젝트의 공개 이름은 자동으로 들어갑니다.
프로젝트 지원 이메일만 선택 후 저장 버튼을 클릭합니다
그러면 최신 구성 파일 다운로드에 대한 안내 내요이 뜨면서 프로젝트 설정에서 SHA-1 인증서를 구성하고 google-services.json을 다운로드하라고 나와있습니다
Android 앱에 대한 Google 로그인을 설정하려면 프로젝트 설정에서 각 앱에 대해 SHA-1 디지털 지문을 추가해야하기 때문입니다
왜냐하면 Google Play 서비스를 이용하려면 서명 인증서의 SHA-1을 제공해야 앱에 대한 OAuth2 클라이언트 및 API 키를 생성할 수 있습니다
그러면 SHA-1 디지털 지문을 추가하고 프로젝트에서 설정해보겠습니다
SHA-1은 암호화 해시 함수에서 가장 많이 쓰이며 TLS, SSL, PGP, SSH, IPSec 등
많은 보안 프로토콜과 프로그램에서 사용되고 있습니다.
SHA-1 디지털 지문 추가하기
[참고]는 Android 스튜디오에서 새 업로드 키 및 키 저장소 생성을 생성하는 방식입니다
저는 터미널을 열고 명령어와 함께 keytool을 사용하여 업로드 키에서 공개 인증서를 생성해보겠습니다
1. 터미널을 열고 OS를 확인하여 아래 경로로 이동합니다
- OS X 및 Linux: ~/.android
- Windows XP: C:\Documents and Settings\user\.android
- Windows Vista 및 Windows 7, 8, 10: C:\Users\user\.android
2. 해당 경로에 release.keystore&debug.keystore을 추가해줍니다
debug.keystore인 이유는 Android 스튜디오에서 프로젝트를 처음 실행하거나 디버그 하면
IDE가 자동으로 $HOME/.android/debug.keystore에 디버그 키 저장소와 인증서를 만들고
키 저장소 비밀번호와 키 번호를 설정하기 때문입니다
# debug.keystore
keytool -genkeypair -v -keystore debug.keystore -alias alias_name -keyalg RSA - keysize 2048 -validity 10000
# release.keystore
keytool -genkeypair -v -keystore release.keystore -alias alias_name -keyalg RSA - keysize 2048 -validity 10000
위에 명령어를 입력하면 패스워드 및 인증서에 사용할 본인 관련 정보를 입력하면 생성됩니다.
키 생성 시 속성 정보는 안드로이드 공식 문서와 keytool를 참고했습니다
- keystore : named.keystore로 현재 디렉터리에 생성
- keyalg RSA : 키 알고리즘 RSA로 설정
RSA은 공개키 암호 알고리즘 중의 하나 중 하나입니다
안드로이드 공식 문서에 따르면 "2012년부터 연간 만료되는 지수 65537의 2048비트 RSA 서명이 허용되었습니다."라고
나와있고 키 크기가 클수록 정수를 계산하기 어렵기 때문에 암호화 알고리즘으로 RSA로 설정했습니다
아래는 안드로이드에서 지원하는 키 알고리즘입니다
https://developer.android.com/training/articles/keystore - keysize : 2048 (-genkeypair and -keyalg is "RSA")
(저전력 StroingBox 구현을 지원하기 위해 RSA 알고리즘의 키 크기는 2048입니다)
-keysize
2048 (when using -genkeypair and -keyalg is "RSA")
1024 (when using -genkeypair and -keyalg is "DSA")
256 (when using -genkeypair and -keyalg is "EC")
56 (when using -genseckey and -keyalg is "DES")
168 (when using -genseckey and -keyalg is "DESede")
- validity : 키가 유효하게 유지되는 날입니다
최소 25년 동안 유효하게 유지되어야 앱 수명 동안 같은 키로 앱 업데이트에 서명할 수 있습니다
그러면 생성된 키에서 인증서 지문을 가져와 추가해보겠습니다
keytool -list -v -keystore debug.keystore -alias alias_name
keytool -list -v -keystore release.keystore -alias alias_name
적합한 시작 날짜: Mon Aug 08 13:47:49 KST 2022 종료 날짜: Wed Jul 31 13:47:49 KST 2052
인증서 지문:
SHA1: <SHA1 VALUE>
SHA256: <SHA256 VALUE>
그러면 SHA1와 SHA256에 값을 확인했습니다!
이제 프로젝트 설정에서 디지털 지문을 추가해보겠습니다
프로젝트 디지털 지문 추가하기
먼저 프로젝트 설정을 클릭해줍니다
그러면 하단에 SHA 인증서에서 디지털 지문 추가 버튼이 보입니다
디지털 추가 후 SHA1, SHA256 값을 각각 추가해주고 google-services.json을 다운로드하여 다시 추가해줍니다
Flutter에서 Firebase 인증 시작하기
https://firebase.google.com/docs/auth/flutter/start
firebase_auth 플러그인 설치
Flutter 프로젝트의 루트에서 다음 명령을 실행하여 플러그인을 설치합니다.
flutter pub add firebase_auth
현재 인증 상태 확인은 : [참고]
비밀번호, 이메일, 전화번호 등 인증할 수 있지만 이번에는 구글 계정을 연결해보겠습니다
여러 인증 공급자를 계정에 연결 [링크]
firebase 문서에서 인증 공급자 자격 증명을 기존 사용자 계정에 연결하기 위해서 아래와 같은 설명을 하고 있습니다
1. 인증 공급자 또는 방법을 사용하여 사용자를 로그인
2. signInWith - 메서드 중 하나를 호출할 때까지 새 인증 공급자에 대한 로그인 흐름을 완료합니다.
3. 새 인증 공급자에 대한 Credential 개체를 가져오기
// Google Sign-in
final credential = GoogleAuthProvider.credential(idToken: idToken);
4. Credential 객체를 로그인 사용자의 linkWithCredential() 메서드에 전달합니다.
try {
final userCredential = await FirebaseAuth.instance.currentUser
?.linkWithCredential(credential);
} on FirebaseAuthException catch (e) {
switch (e.code) {
case "provider-already-linked":
print("The provider has already been linked to the user.");
break;
case "invalid-credential":
print("The provider's credential is not valid.");
break;
case "credential-already-in-use":
print("The account corresponding to the credential already exists, "
"or is already linked to a Firebase User.");
break;
// See the API reference for the full list of error codes.
default:
print("Unknown error.");
}
linkWithCredential() 호출이 성공하면 사용자는 이제 연결된 인증 제공자를 사용하여 로그인하고
동일한 Firebase 데이터에 액세스 할 수 있습니다.
구글 로그인
Firebase 문서에서 GoogleAuthProvider.credential 메서드를 확인해보면 아래와 같습니다
static OAuthCredential credential({String? idToken, String? accessToken}) {
assert(accessToken != null || idToken != null,
'At least one of ID token and access token is required');
return GoogleAuthCredential._credential(
idToken: idToken,
accessToken: accessToken,
);
}
GoogleAuthCredential값을 가져오기 위해서는 idToken과 accessToken이 필요합니다
그렇기 때문에 로그인할 계정에 idToken과 accessToken을 얻기 위해서는 OAuth 2.0을 사용하여 Google API에 액세스 해야 합니다
google_sign_in
https://pub.dev/packages/google_sign_in
그러면 위의 플러그인을 설치해서 idToken과 accessToken을 얻어보겠습니다
flutter pub add google_sign_in
설치를 하고 나면 이제 GoogleSignIn().signIn()를 사용하여 로그인을 성공하면 사용자 정보와 인증을 가져올 수 있습니다
Future<void> _handleSignIn() async {
try {
await _googleSignIn.signIn();
} catch (error) {
print(error);
}
}
그러면 이제 아래와 같이 진행해보겠습니다
1. 로그인을 성공한다
2. 사용자의 idToken, accessToken 값을 가져온다
3. GoogleAuthProvider.credential(idToken, accessToken) 메서드에 전달
4. AuthCredential 객체를 사용자의 signInWithCredential() 또는 linkWithCredential() 메서드에 전달
Future<UserCredential> signInWithGoogle() async {
final GoogleSignInAccount? googleUser = await GoogleSignIn().signIn();
final GoogleSignInAuthentication? googleAuth =
await googleUser?.authentication;
final credential = GoogleAuthProvider.credential(
accessToken: googleAuth?.accessToken,
idToken: googleAuth?.idToken,
);
return await FirebaseAuth.instance.signInWithCredential(credential);
}
UserCredential은 인증 요청에서 사용자 자격 증명이 반환 객체입니다
UserCredential을 객체를 통해 우리는 이 사용자가 신규 사용자인지 아니면 기존 사용자인지 알 수 있습니다
/// Returns additional information about the user, such as whether they are a
/// newly created one.
AdditionalUserInfo? get additionalUserInfo => _delegate.additionalUserInfo;
/// The users [AuthCredential].
AuthCredential? get credential => _delegate.credential;
/// Returns a [User] containing additional information and user specific
/// methods.
User? get user {
// TODO(rousselGit): cache the `user` instance or override == so that ".user == .user"
return _delegate.user == null ? null : User._(_auth, _delegate.user!);
}
그래서 신규 사용자이면 가입 성공 상태로 추가 정보 입력을 위해 회원 가입 화면으로 이동하고 로그인이 성공한 경우
홈 화면으로 이동하게 작업해봤습니다
ElevatedButton.icon(
onPressed: () async {
await FirebaseAuthProvider().loginWithGoogle().then((loginStatus) {
if(loginStatus == AuthStatus.loginSuccess) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
);
} else if(loginStatus == AuthStatus.registerSuccess){
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SignUpScreen()),
);
}
});
},
...
)
그리고 이제 구글 로그인 버튼을 클릭하면!
이렇게 쏙!! 완료했습니다!
'IT > 기록' 카테고리의 다른 글
[Flutter] ClipRRect Widget - 이미지 테두리를 둥글게 만들고 싶을 때 (0) | 2022.10.14 |
---|---|
우분투 Jenkins 설치하기 (0) | 2022.08.12 |
[Flutter] Flutter 앱에 Firebase 파이어베이스 설정하기 (0) | 2022.08.08 |
21년 12월 JAVA 보안 취약점 이슈와 API 보안에 대해 학습 (0) | 2022.08.04 |
gradle project에서 JMH 라이브러리를 이용해 java code 성능 측정 (0) | 2022.08.03 |