공부/Android

Google Login, Google People Api 로 사용자의 구글 계정 정보를 알아내보자~ 2편

데자와 맛있다 2024. 7. 21. 10:56

지난 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

 

REST Resource: people.connections  |  People API  |  Google for Developers

이 페이지는 Cloud Translation API를 통해 번역되었습니다. REST Resource: people.connections 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 리소스: Person 인증된 사용자

developers.google.com

를 참고하자

 

service

interface PeopleService {
    @GET("people/me")
    suspend fun getGoogleUserInfo(
        @Header("Authorization") header: String,
        @Query("personFields") personFields: String
    )
}

요청 url은

헤더에는 위에서 받은 구글 oauth2 엑세스 토큰
personFields에는 받아야 하는 데이터에 맞게 쿼리 넣으면된다

 

 

 

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 플러그인을 받는다

https://developer88.tistory.com/entry/JSON-to-Kotlin-Class-%ED%94%8C%EB%9F%AC%EA%B7%B8%EC%9D%B8-%ED%86%B5%ED%95%B4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%81%B4%EB%9E%98%EC%8A%A4-%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0

 

JSON to Kotlin Class 플러그인 통해 데이터 클래스 생성하기

API에 대한 작업을 하다보면, JSON형식의 데이터를 kotlin의 data클래스로 만들어야 하는 경우가 생깁니다. 비록 Kotlin이 Java에 비해 데이터 클래스의 코드길이를 상당히 줄여주었음에도, 이 단순 작

developer88.tistory.com

이 블로그를 참고하길

처음할때 하나하나 만드는 뻘짓거리를 하고있었는데 지금 보니 이게 있었음

 

그러면 알아서 이렇게 이쁘게 잘 만들어줌

만들어낸 데이터 클래스를 service 와 repository에 리턴값으로 넣어주고

적재적소에 쓰자