Google Login, Google People Api 로 사용자의 구글 계정 정보를 알아내보자~ 2편
지난 1편에서 개념적인부분에 대해 정리했다.
2편에서는 실제 어떻게 구현하는지 알아보겠다.
구글 로그인 구현
1. 구글 클라우드 콘솔에 들어가서 프로젝트를 만듭니다.
2. 안드로이드 프로젝트를 하나 만들고 디펜던시 설정을 해주세요
//Google Play services
implementation("com.google.gms:google-services:4.3.15")
implementation("com.google.firebase:firebase-auth:22.0.0")
implementation("com.google.firebase:firebase-bom:32.0.0")
implementation("com.google.android.gms:play-services-auth:20.5.0")
3. 안드로이드 프로젝트 sha-1 해시값을 구합니다
나타나는 창에 gradle signingReport 를 입력한다
sha1 복사
3. client id 만든다
이후 나타난 화면에 필요 정보를 입력하고 그 다음 범위 추가 화면부터는 별다른 설정없이 다음으로 넘어간다.
다음 다시 사용자 인증정보 만들기로 간다
웹 어플리케이션으로 하고 클라이언트 id를 만든다
같은 방법으로 안드로이드 어플리케이션으로 하고 클라이언트 id를 만든다
이때 복사해둔 sha1 값과 패키지이름을 넣는다.
4. 안드로이드 코드 작성
private val signInLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
val task = GoogleSignIn.getSignedInAccountFromIntent(result.data)
try { // 사용자 구글 로그인 성공
val account: GoogleSignInAccount = task.getResult(ApiException::class.java)
Log.d("google login info", "이름: ${account.givenName} \n 성: ${account.familyName}\n 닉네임: ${account.displayName}\n Sub Id: ${account.id}\n프로필: ${account.photoUrl}")
Log.d("google login info", "res: ${result.data}")
Log.d("server auth code", "server auth code: ${account.serverAuthCode} ")
Log.d("TAG", "idToken: ${account.idToken}")
} catch (e: ApiException) { // 사용자 구글 로그인 실패 (뒤로가기 등..)
}
}
private fun googleLogin() {
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(여기에 발급받은 client id 입력)
.requestServerAuthCode(여기에 발급받은 client id 입력)
.requestId()
.requestProfile()
.requestEmail()
.requestScopes(
Scope(Scopes.PROFILE),
Scope(Scopes.EMAIL),
Scope(Scopes.OPEN_ID)
)
.build()
val googleSignInClient = GoogleSignIn.getClient(requireContext(), gso)
val signInIntent: Intent = googleSignInClient.signInIntent
signInLauncher.launch(signInIntent)
}
클라이언트id를 복사하고(웹 클라이언트 id) 위 코드에서 requestIdToken, requestServerAuthCode 에 넣는다
실행 후 아무 아이디로 로그인한다
로그가 찍히면 된거
구글 oauth2 토큰 받기
위 코드에서 찍는 idToken은 OICD 에서 받는 idToken이다
이 값을 이용해서 구글 oauth2 토큰을 받아보자
요청 body
data class LoginGoogleRequestModel(
@SerializedName("grant_type")
private val grantType: String,
@SerializedName("client_id")
private val clientId: String,
@SerializedName("client_secret")
private val clientSecret: String,
@SerializedName("code")
private val code: String?
)
응답
data class LoginGoogleResponseModel(
@SerializedName("access_token") var accessToken: String,
)
service
interface GoogleAuthService {
@POST("oauth2/v4/token")
suspend fun getAccessToken(
@Body request: LoginGoogleRequestModel
): Response<LoginGoogleResponseModel>
}
요청 url은
LoginGoogleRequestModel(
grantType = "authorization_code",
clientId = 여기에 클라이언트 id를 넣으세요,
clientSecret = 여기에 클라이언트 secreat 을 넣으세요,
code = account.serverAuthCode
)
요청을 보낼때는 위 처럼 값을 채워서 보내면 되는데
code는 위에서 본 signInLauncher 의 account값에서 serverAuthCode라는 값을 넣어주면된다
clientId 는 앞서 복사해둔 웹 클라이언트 id 를 넣으면 되고
client secret은
위 이미지처럼 웹 클라이언트 옆에 다운로드를 눌러 json을 받고
json파일을 열면 끝쪽에 client secret이 있다. 그 값을 넣으면된다.
참고로 client secret은 외부 공개해서는 안되는값이다.. 그러니깐 앱 안에 그냥 넣는것은 고려해보는게 좋겠다
(client secret을 안넣고 oauth토큰을 얻어오는 방법을 좀 찾아봐야될거같긴함)
People API 사용하기
1. 디펜던시
// people
implementation("com.google.apis:google-api-services-people:v1-rev20220531-2.0.0")
implementation("com.google.api-client:google-api-client-android:1.33.2")
2. scope 설정
받기 원하는 데이터에 대해 scope 설정을 해야 한다
scope는 지난편에서 말했듯이 받기 원하는 데이터에 대해 설정하는것이다
이번예시에서는 생년월일, 성별을 받도록하겠다
scope는 구글 로그인쪽에 설정해야한다
private fun googleLogin() {
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken("")
.requestServerAuthCode("")
.requestId()
.requestProfile()
.requestEmail()
.requestScopes(
Scope(Scopes.PROFILE),
Scope(Scopes.EMAIL),
Scope(Scopes.OPEN_ID),
Scope(PeopleServiceScopes.USER_BIRTHDAY_READ),//스코프 추가
Scope(PeopleServiceScopes.USER_GENDER_READ)//스코프 추가
)
.build()
val googleSignInClient = GoogleSignIn.getClient(requireContext(), gso)
val signInIntent: Intent = googleSignInClient.signInIntent
signInLauncher.launch(signInIntent)
}
어떤 데이터를 가져올수있는지는
https://developers.google.com/people/api/rest/v1/people.connections
를 참고하자
service
interface PeopleService {
@GET("people/me")
suspend fun getGoogleUserInfo(
@Header("Authorization") header: String,
@Query("personFields") personFields: String
)
}
요청 url은
repository
class GoogleAuthRepository (
private val retrofit: Retrofit,
private val googleAuthService: GoogleAuthService,
private val peopleService: PeopleService
) {
suspend fun getGoogleAccessToken(
loginGoogleRequestModel: LoginGoogleRequestModel
): Response<LoginGoogleResponseModel> {
return googleAuthService.getAccessToken(loginGoogleRequestModel)
}
suspend fun getPeopleData(
token: String,
personFields: String = "birthdays,genders"
) {
peopleService.getGoogleUserInfo(
header = "Bearer $token",
personFields = personFields
)
}
}
그리고 구글 클라우드 콘솔에서 people api 사용설정을 해야 한다
위와 같은 과정으로 사용 설정하면 된다
코드를 실행하면 응답이 아래와 같이 온다
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I {
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "resourceName": "people/id값",
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "etag": "",
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "genders": [
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I {
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "metadata": {
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "primary": true,
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "source": {
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "type": "PROFILE",
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "id": "id값"
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I }
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I },
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "value": "female",
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "formattedValue": "Female"
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I }
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I ],
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "birthdays": [
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I {
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "metadata": {
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "primary": true,
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "source": {
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "type": "ACCOUNT",
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "id": ""
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I }
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I },
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "date": {
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "year": 1999,
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "month": 4,
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I "day": 25
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I }
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I }
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I ]
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I }
2024-07-21 10:34:55.569 13548-13723 okhttp.OkHttpClient com.dodo.myapplication I <-- END HTTP (602-byte body)
값을 복사해두자..
그리고 안드로이드 스튜디오에 json to kotlin class 플러그인을 받는다
이 블로그를 참고하길
처음할때 하나하나 만드는 뻘짓거리를 하고있었는데 지금 보니 이게 있었음
그러면 알아서 이렇게 이쁘게 잘 만들어줌
만들어낸 데이터 클래스를 service 와 repository에 리턴값으로 넣어주고
적재적소에 쓰자