gpt4 book ai didi

java - 如何从 GoogleCredential 迁移到 GoogleCredentials 并且仍然可以访问 People API?

转载 作者:行者123 更新时间:2023-12-04 12:00:07 28 4
gpt4 key购买 nike

背景
对于我正在开发的应用程序,它使用 People API 使用凭据(用户登录)。用户提供凭据后,我可以访问各种 Google API,例如 People API。一个示例是获取联系人列表:
https://developers.google.com/people/api/rest/v1/people.connections/list
我注意到类 com.google.api.client.googleapis.auth.oauth2.GoogleCredential已弃用:
https://googleapis.dev/java/google-api-client/latest/com/google/api/client/googleapis/auth/oauth2/GoogleCredential.html
问题
该应用程序具有基于某些旧 G+ 代码 (here) 的旧代码,可通过 Google 帐户联系联系人。这是其中最重要部分的一个 fragment ,这让我难以摆脱它:

object GoogleOuthHelper {
@WorkerThread
fun setUp(context: Context, serverAuthCode: String?): Services {
val httpTransport: HttpTransport = NetHttpTransport()
val jsonFactory = JacksonFactory.getDefaultInstance()
// Redirect URL for web based applications. Can be empty too.
val redirectUrl = "urn:ietf:wg:oauth:2.0:oob"
// Exchange auth code for access token
val tokenResponse = GoogleAuthorizationCodeTokenRequest(
httpTransport, jsonFactory, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
serverAuthCode, redirectUrl)
.execute()
// Then, create a GoogleCredential object using the tokens from GoogleTokenResponse
val credential = GoogleCredential.Builder()
.setClientSecrets(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
.setTransport(httpTransport)
.setJsonFactory(jsonFactory)
.build()
val accessToken = tokenResponse.accessToken
getDefaultSecuredSharedPreferences(context).edit()
.putString(SecuredSharedPreferences.KEY__GOOGLE_ACCESS_TOKEN, accessToken).apply()
credential.setFromTokenResponse(tokenResponse)
val appPackageName = context.packageName
val peopleServiceApi = PeopleService.Builder(httpTransport, jsonFactory, credential)
.setApplicationName(appPackageName)
.build()
val peopleService = peopleServiceApi.people()
val otherContactsService = peopleServiceApi.otherContacts()
val contactGroups = peopleServiceApi.contactGroups()
return Services(peopleService, otherContactsService, contactGroups)
}

class Services(
/**https://developers.google.com/people/api/rest/v1/people*/
val peopleService: PeopleService.People,
/**https://developers.google.com/people/api/rest/v1/otherContacts*/
val otherContactsService: OtherContacts,
/**https://developers.google.com/people/api/rest/v1/contactGroups*/
val contactGroups: ContactGroups)
}
问题甚至从一开始就存在:
类(class) GoogleCredentials似乎不接受我在 GoogleCredential 上得到的任何东西类(class)。
要添加更多内容,此函数将“serverAuthCode”作为参数,来自 GoogleSignInAccount ,但要得到它,我需要使用已弃用的 GoogleApiClient类(class):
        fun prepareGoogleApiClient(someContext: Context): GoogleApiClient {
val context = someContext.applicationContext ?: someContext
val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestServerAuthCode(GOOGLE_CLIENT_ID)
.requestEmail()
.requestScopes(
Scope(PeopleServiceScopes.CONTACTS_READONLY),
Scope(PeopleServiceScopes.USERINFO_PROFILE),
Scope(PeopleServiceScopes.USER_EMAILS_READ),
Scope(PeopleServiceScopes.CONTACTS),
Scope(PeopleServiceScopes.CONTACTS_OTHER_READONLY)
)
.build()
return GoogleApiClient.Builder(context)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build()
}
这就是我用它做的:
val connectionResult = googleApiClient!!.blockingConnect()
if (!connectionResult.isSuccess)
return
val operation = Auth.GoogleSignInApi.silentSignIn(googleApiClient)
val googleSignInResult: GoogleSignInResult = operation.await()
val googleSignInAccount = googleSignInResult.signInAccount
//use googleSignInAccount.serverAuthCode in setUp() function above
Gradle 文件具有以下依赖项:
// https://mvnrepository.com/artifact/com.google.auth/google-auth-library-oauth2-http
implementation 'com.google.auth:google-auth-library-oauth2-http:0.26.0'
// https://github.com/googleapis/google-api-java-client-services/tree/master/clients/google-api-services-people/v1#gradle https://mvnrepository.com/artifact/com.google.apis/google-api-services-people
implementation 'com.google.apis:google-api-services-people:v1-rev20210515-1.31.0'
我试过的
除了查看文档(并且没有看到与我必须处理的相似之处)之外,我还尝试在这里写下这个。
可悲的是,我还找不到如何从旧代码中迁移出来。
我试图在那里问我如何迁移( herehere )但还没有得到答案。
问题
如何从 GoogleCredential 迁移出去至 GoogleCredentials同时还在使用各种 API,例如 People API?
换句话说:如何避免在 Android 上使用这些已弃用的类(GoogleCredential 和 GoogleApiClient),同时仍然能够使用各种 API?

最佳答案

How can I migrate away from GoogleCredential to GoogleCredentials while still using the various APIs such as People API?

In other words: How can I avoid using any of those deprecated classes (GoogleCredential and GoogleApiClient), on Android, while still being able to use the various APIs?


尽管您可以使 GoogleCredentials 直接工作,但最好使用从 GoogleCredentials 派生的类,例如 UserCredentials,它可以像 GoogleCredential 一样适应 token 刷新。 GoogleCredentials 更像是一个基础类。
以下代码使用了 UserCredentials。这主要是您介绍的内容,但为了演示的目的,我更改了一些凭证存储逻辑。除了 startActivityForResult() 之外,此代码没有不推荐使用的方法. serverAuthCode可从 GoogleSignInAccount 获得。看看 Moving Past GoogleApiClient关于如何删除对 GoogleApiClient 的依赖。我更新了我的 public gist来自 Google 的 RestApiActivity signin quickstart它展示了如何使用 GoogleOauthHelper 以及 GoogleApi。
GoogleOauthHelper.kt
object GoogleOauthHelper {
@WorkerThread
fun setUp(context: Context, serverAuthCode: String?): Services {
val httpTransport: HttpTransport = NetHttpTransport()
val jsonFactory = GsonFactory.getDefaultInstance()
// Redirect URL for web based applications. Can be empty too.
val redirectUrl = "urn:ietf:wg:oauth:2.0:oob"

// Patch for demo
val GOOGLE_CLIENT_ID = context.getString(R.string.GOOGLE_CLIENT_ID)
val GOOGLE_CLIENT_SECRET = context.getString(R.string.GOOGLE_CLIENT_SECRET)

var accessToken: AccessToken? = null
var refreshToken =
getDefaultSecuredSharedPreferences(context).getString(
SecuredSharedPreferences.KEY_GOOGLE_REFRESH_TOKEN,
null
)

if (refreshToken == null) {
/* Did we lose the refresh token, or is this the first time? Refresh tokens are only
returned the first time after the user grants us permission to use the API. So, if
this is the first time doing this, we should get a refresh token. If it's not the
first time, we will not get a refresh token, so we will proceed with the access
token alone. If the access token expires (in about an hour), we will get an error.
What we should do is to ask the user to reauthorize the app and go through the
OAuth flow again to recover a refresh token.

See https://developers.google.com/identity/protocols/oauth2#expiration regarding
how a refresh token can become invalid.
*/
val tokenResponse = GoogleAuthorizationCodeTokenRequest(
httpTransport, jsonFactory, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
serverAuthCode, redirectUrl
).execute()

refreshToken = tokenResponse.refreshToken
if (refreshToken != null) {
getDefaultSecuredSharedPreferences(context).edit()
.putString(SecuredSharedPreferences.KEY_GOOGLE_REFRESH_TOKEN, refreshToken)
.apply()
} else {
Log.d("Applog", "No refresh token. Going with access token alone.")
val expiresAtMilliseconds =
Clock.SYSTEM.currentTimeMillis() + tokenResponse.expiresInSeconds * 1000
accessToken = AccessToken(tokenResponse.accessToken, Date(expiresAtMilliseconds))
}
}

Log.d("Applog", "Refresh token: $refreshToken")
// UserCredentials extends GoogleCredentials and permits token refreshing.
val googleCredentials = UserCredentials.newBuilder().run {
clientId = GOOGLE_CLIENT_ID
clientSecret = GOOGLE_CLIENT_SECRET
setRefreshToken(refreshToken)
setAccessToken(accessToken)
build()
}

// Save access token on change
googleCredentials.addChangeListener { oAuth2Credentials ->
saveAccessToken(oAuth2Credentials.accessToken)
}

val requestInitializer: HttpRequestInitializer = HttpCredentialsAdapter(googleCredentials)
val appPackageName = context.packageName

val peopleServiceApi = PeopleService.Builder(httpTransport, jsonFactory, requestInitializer)
.setApplicationName(appPackageName)
.build()

return peopleServiceApi.run { Services(people(), otherContacts(), contactGroups()) }
}

private fun saveAccessToken(accessToken: AccessToken) {
// Persist the token securely.
Log.d("Applog", "Access token has changed: ${accessToken.tokenValue}")
}

// Warning insecure!: Patch for demo.
private fun getDefaultSecuredSharedPreferences(context: Context): SharedPreferences {
return PreferenceManager.getDefaultSharedPreferences(context)
}

// Warning insecure!: Patch for demo.
object SecuredSharedPreferences {
const val KEY_GOOGLE_REFRESH_TOKEN = "GOOGLE_REFRESH_TOKEN"
}

class Services(
/**https://developers.google.com/people/api/rest/v1/people*/
val peopleService: PeopleService.People,
/**https://developers.google.com/people/api/rest/v1/otherContacts*/
val otherContactsService: PeopleService.OtherContacts,
/**https://developers.google.com/people/api/rest/v1/contactGroups*/
val contactGroups: PeopleService.ContactGroups,
)
}
我已经发布了 demo project在 GitHub 上。

关于java - 如何从 GoogleCredential 迁移到 GoogleCredentials 并且仍然可以访问 People API?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67500479/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com