연결된 계정 로그인을 사용하면 사용자가 Google 계정으로 원탭 로그인을 사용할 수 있습니다. Google 계정이 이미 서비스에 연결되어 있습니다. 이렇게 하면 사용자 환경을 개선할 수 있게 해 줍니다. 사용자 이름과 비밀번호입니다. 또한 사용자가 서비스에서 중복 계정을 만들 가능성도 줄어듭니다.
연결된 계정 로그인은 Android 즉, 앱이 기본 라이브러리를 제공하는 경우 별도의 라이브러리를 이미 원탭 기능이 사용 설정되어 있습니다.
이 문서에서는 연결된 계정 로그인을 지원하도록 Android 앱을 수정하는 방법을 설명합니다.
작동 방식
- 원탭 로그인 절차 중에 연결된 계정을 표시하도록 선택합니다.
- 사용자가 Google에 로그인하고 Google 계정을 사용자 계정에 연결된 경우 연결된 있습니다.
- 사용자에게 계정에 로그인할 수 있는 옵션과 함께 원탭 로그인 메시지가 표시됩니다. 서비스에 연결할 수 있습니다.
- 사용자가 연결된 계정을 계속 사용하기로 선택하면 사용자의 ID 토큰이 앱에 반환됩니다. 이 토큰을 사용하여 로그인한 사용자를 식별합니다.
설정
개발 환경 설정
개발 호스트에서 최신 Google Play 서비스를 가져옵니다.
- Google 검색 앱 홈 화면의 오른쪽 상단에 있는 Android SDK Manager
SDK Tools에서 Google Play 서비스를 찾습니다.
이 패키지의 상태가 '설치됨'이 아닌 경우 둘 다 선택하고 '설치'를 클릭합니다. 패키지 설치
앱 구성
프로젝트 수준
build.gradle
파일에 Google의 Maven 저장소를 포함합니다.buildscript
및allprojects
섹션 모두에서 확인할 수 있습니다.buildscript { repositories { google() } } allprojects { repositories { google() } }
모듈의 앱 수준 Gradle 파일(일반적으로
app/build.gradle
)에 'Link with Google' API의 종속 항목을 추가합니다.dependencies { implementation 'com.google.android.gms:play-services-auth:21.2.0' }
연결된 계정 로그인을 지원하도록 Android 앱 수정
연결된 계정 로그인 과정이 끝나면 있습니다. 사용자가 로그인하기 전에 ID 토큰의 무결성을 확인해야 합니다.
다음 코드 샘플은 ID 토큰을 확인하고 로그인합니다.
로그인 인텐트의 결과를 수신하는 활동 만들기
Kotlin
private val activityResultLauncher = registerForActivityResult( ActivityResultContracts.StartIntentSenderForResult()) { result -> if (result.resultCode == RESULT_OK) { try { val signInCredentials = Identity.signInClient(this) .signInCredentialFromIntent(result.data) // Review the Verify the integrity of the ID token section for // details on how to verify the ID token verifyIdToken(signInCredential.googleIdToken) } catch (e: ApiException) { Log.e(TAG, "Sign-in failed with error code:", e) } } else { Log.e(TAG, "Sign-in failed") } }
자바
private final ActivityResultLauncher<IntentSenderResult> activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartIntentSenderForResult(), result -> { If (result.getResultCode() == RESULT_OK) { try { SignInCredential signInCredential = Identity.getSignInClient(this) .getSignInCredentialFromIntent(result.getData()); verifyIdToken(signInCredential.getGoogleIdToken()); } catch (e: ApiException ) { Log.e(TAG, "Sign-in failed with error:", e) } } else { Log.e(TAG, "Sign-in failed") } });
로그인 요청 빌드
Kotlin
private val tokenRequestOptions = GoogleIdTokenRequestOptions.Builder() .supported(true) // Your server's client ID, not your Android client ID. .serverClientId(getString("your-server-client-id") .filterByAuthorizedAccounts(true) .associateLinkedAccounts("service-id-of-and-defined-by-developer", scopes) .build()
자바
private final GoogleIdTokenRequestOptions tokenRequestOptions = GoogleIdTokenRequestOptions.Builder() .setSupported(true) .setServerClientId("your-service-client-id") .setFilterByAuthorizedAccounts(true) .associateLinkedAccounts("service-id-of-and-defined-by-developer", scopes) .build()
로그인 대기 중 인텐트 실행
Kotlin
Identity.signInClient(this) .beginSignIn( BeginSignInRequest.Builder() .googleIdTokenRequestOptions(tokenRequestOptions) .build()) .addOnSuccessListener{result -> activityResultLauncher.launch(result.pendingIntent.intentSender) } .addOnFailureListener {e -> Log.e(TAG, "Sign-in failed because:", e) }
자바
Identity.getSignInClient(this) .beginSignIn( BeginSignInRequest.Builder() .setGoogleIdTokenRequestOptions(tokenRequestOptions) .build()) .addOnSuccessListener(result -> { activityResultLauncher.launch( result.getPendingIntent().getIntentSender()); }) .addOnFailureListener(e -> { Log.e(TAG, "Sign-in failed because:", e); });
ID 토큰의 무결성 확인
토큰이 유효한지 확인하려면 다음을 확인하세요. 다음 기준을 충족해야 합니다.
- Google에서 ID 토큰을 올바르게 서명했는지 확인합니다. Google의 공개 키 사용
(제공:
JWK 또는
PEM 형식)
토큰의 서명을 확인합니다 이러한 키는 정기적으로 순환됩니다. 검사하다
응답의
Cache-Control
헤더를 통해 다시 가져와야 합니다 - ID 토큰의
aud
값은 앱의 클라이언트 ID를 찾습니다. 이 검사는 악의적인 행위자에게 발급된 ID 토큰을 앱의 백엔드 서버에서 동일한 사용자에 대한 데이터에 액세스하는 데 사용되는 앱. - ID 토큰의
iss
값은 다음과 같습니다.accounts.google.com
또는https://accounts.google.com
입니다. - ID 토큰의 만료 시간 (
exp
)이 지나지 않았습니다. - ID 토큰이 Google Workspace 또는 Cloud를 나타내는지 확인해야 하는 경우
조직 계정에 대한
hd
클레임을 확인하면 사용자 도메인입니다. 리소스에 대한 액세스 권한을 특정 도메인을 사용하는 경우가 많습니다 이 소유권 주장이 없으면 계정이 다음에 속하지 않음을 나타냅니다. Google이 호스팅하는 도메인입니다.
email
, email_verified
, hd
필드를 사용하면
Google은 이메일 주소를 호스팅하고 이에 대한 권한이 있습니다. Google이 공신력 있는 경우
합법적인 계정 소유자로 알려진 경우 비밀번호나 기타 로그인 정보를 건너뛸 수
챌린지 방법.
Google이 신뢰할 수 있는 케이스:
email
의 접미사는@gmail.com
입니다. 이 계정은 Gmail 계정입니다.email_verified
이(가) true이고hd
이(가) 설정되어 있습니다. 이는 G Suite 계정입니다.
사용자는 Gmail 또는 G Suite를 사용하지 않고도 Google 계정에 등록할 수 있습니다. 날짜
email
에 @gmail.com
서픽스가 포함되어 있지 않고 hd
가 없는 경우 Google은 포함되지 않음
신뢰할 수 있는 비밀번호나 다른 본인 확인 방법을 사용하여
있습니다. Google에서 처음에 확인했으므로 email_verified
도 true일 수 있습니다.
사용자에게 양도할 수 있지만 제3자의 소유권은
이메일 계정이 변경되었을 수 있습니다.
이러한 확인 단계를 수행하기 위해 직접 코드를 작성하는 대신 Google에서는
플랫폼에 Google API 클라이언트 라이브러리를 사용하거나
JWT 라이브러리도 있습니다. 개발 및 디버깅을 위해 tokeninfo
를 호출할 수 있습니다.
엔드포인트가 있습니다
Google API 클라이언트 라이브러리 사용
Java Google API 클라이언트 라이브러리 프로덕션 환경에서 Google ID 토큰의 유효성을 검사하는 데 권장되는 방법입니다.
자바
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken.Payload;
import com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier;
...
GoogleIdTokenVerifier verifier = new GoogleIdTokenVerifier.Builder(transport, jsonFactory)
// Specify the CLIENT_ID of the app that accesses the backend:
.setAudience(Collections.singletonList(CLIENT_ID))
// Or, if multiple clients access the backend:
//.setAudience(Arrays.asList(CLIENT_ID_1, CLIENT_ID_2, CLIENT_ID_3))
.build();
// (Receive idTokenString by HTTPS POST)
GoogleIdToken idToken = verifier.verify(idTokenString);
if (idToken != null) {
Payload payload = idToken.getPayload();
// Print user identifier
String userId = payload.getSubject();
System.out.println("User ID: " + userId);
// Get profile information from payload
String email = payload.getEmail();
boolean emailVerified = Boolean.valueOf(payload.getEmailVerified());
String name = (String) payload.get("name");
String pictureUrl = (String) payload.get("picture");
String locale = (String) payload.get("locale");
String familyName = (String) payload.get("family_name");
String givenName = (String) payload.get("given_name");
// Use or store profile information
// ...
} else {
System.out.println("Invalid ID token.");
}
GoogleIdTokenVerifier.verify()
메서드는 JWT 서명을 확인합니다.
aud
소유권 주장, iss
소유권 주장, 그리고 exp
소유권 주장.
ID 토큰이 Google Workspace 또는 Cloud를 나타내는지 확인해야 하는 경우
조직 계정의 경우 도메인 이름을 확인하여 hd
소유권 주장을 확인할 수 있습니다.
Payload.getHostedDomain()
메서드에서 반환됩니다.
tokeninfo 엔드포인트 호출
디버깅을 위해 ID 토큰 서명을 검증하는 쉬운 방법은
tokeninfo
엔드포인트를 사용합니다. 이 엔드포인트를 호출할 때는
IP 주소를 제대로 테스트하면서 대부분의 유효성 검사를 자동으로 수행하는
페이로드 추출을 사용할 수 있습니다. 프로덕션에는 사용하기에 적합하지 않습니다.
요청이 제한되거나 간헐적인 오류가 발생할 수 있기 때문입니다.
tokeninfo
엔드포인트를 사용하여 ID 토큰을 검증하려면 HTTPS를 만드세요.
POST 또는 GET 요청을 전송하고
id_token
매개변수
예를 들어 토큰 'XYZ123'의 유효성을 검사하려면 다음 GET 요청을 실행합니다.
https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
토큰이 올바르게 서명되었고 iss
및 exp
이
클레임이 예상값을 갖는 경우 HTTP 200 응답을 받게 됩니다. 여기서 본문은
에는 JSON 형식의 ID 토큰 클레임이 포함됩니다.
응답 예시는 다음과 같습니다.
{ // These six fields are included in all Google ID Tokens. "iss": "https://accounts.google.com", "sub": "110169484474386276334", "azp": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "aud": "1008719970978-hb24n2dstb40o45d4feuo2ukqmcc6381.apps.googleusercontent.com", "iat": "1433978353", "exp": "1433981953", // These seven fields are only included when the user has granted the "profile" and // "email" OAuth scopes to the application. "email": "testuser@gmail.com", "email_verified": "true", "name" : "Test User", "picture": "https://lh4.googleusercontent.com/-kYgzyAWpZzJ/ABCDEFGHI/AAAJKLMNOP/tIXL9Ir44LE/s99-c/photo.jpg", "given_name": "Test", "family_name": "User", "locale": "en" }
ID 토큰이 Google Workspace 계정을 나타내는지 확인해야 하는 경우 다음을 확인할 수 있습니다.
사용자의 호스트 도메인을 나타내는 hd
클레임 다음과 같은 경우에 사용해야 합니다.
리소스에 대한 액세스 권한을 특정 도메인의 구성원으로만 제한 본 클레임의 부재
계정이 Google Workspace 호스팅 도메인에 속하지 않음을 나타냅니다.