You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用中通过Google Sign-in实现Pub/Sub认证的方案问询

可行,具体实现方案如下

你完全可以用Google Sign-in获取的用户OAuth 2.0凭据替代服务账号的creds.json来认证Pub/Sub客户端,核心是将Sign-in得到的Access Token转换成Pub/Sub SDK能识别的GoogleCredentials,具体步骤和代码修改如下:

1. 确保Google Sign-in请求Pub/Sub权限

在初始化Google Sign-in时,需要添加Pub/Sub的权限Scope,这样获取到的Access Token才有权限访问你的Pub/Sub订阅:

val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
    .requestEmail()
    // 保留原有的Gmail相关Scope,同时添加Pub/Sub的权限Scope
    .requestScopes(
        Scope(GmailScopes.GMAIL_READONLY),
        Scope("https://www.googleapis.com/auth/pubsub")
    )
    .build()

val googleSignInClient = GoogleSignIn.getClient(context, gso)

2. 用Sign-in的Access Token创建Pub/Sub认证凭据

从已登录的Google账号中获取有效Access Token,将其包装成GoogleCredentials,替换原有的服务账号凭据:

// 获取已登录的用户账号(假设你已完成Sign-in流程)
val signedInAccount = GoogleSignIn.getLastSignedInAccount(context)
signedInAccount?.let { account ->
    // 静默刷新获取有效Access Token(自动处理过期逻辑)
    googleSignInClient.silentSignIn().addOnSuccessListener { signInResult ->
        val accessToken = signInResult.accessToken ?: return@addOnSuccessListener
        
        // 用Access Token创建GoogleCredentials,并指定Pub/Sub的Scope
        val userCredentials = GoogleCredentials.create(
            AccessToken(accessToken.tokenValue, Date(System.currentTimeMillis() + 3600 * 1000))
        ).createScoped(listOf("https://www.googleapis.com/auth/pubsub"))

        // 初始化Pub/Sub Subscriber,替换原有的CredentialsProvider
        val subscriptionName = ProjectSubscriptionName.of("myproject", "my-sub")
        val subscriber = Subscriber.newBuilder(subscriptionName) { message, ackConsumer ->
            Log.d("PUBSUB", "收到消息:${message.data.toStringUtf8()}")
            ackConsumer.ack() // 务必确认消息,避免重复投递
        }
        .setCredentialsProvider { userCredentials }
        .build()

        // 启动订阅(建议用生命周期绑定的CoroutineScope,比如viewModelScope,不要用GlobalScope)
        viewModelScope.launch(Dispatchers.IO) {
            subscriber.startAsync().awaitRunning()
            subscriber.awaitTerminated()
        }
    }.addOnFailureListener {
        // 处理Token刷新失败,比如引导用户重新登录
        Log.e("PUBSUB_AUTH", "Token刷新失败", it)
    }
}

3. 关键注意事项

  • 权限配置:需要在Google Cloud控制台给当前登录的用户(或其所属的Google Workspace账号)授予Pub/Sub订阅者(roles/pubsub.subscriber)角色,目标是你要订阅的Pub/Sub订阅资源。
  • Token过期处理:Access Token默认1小时过期,silentSignIn()会自动刷新有效Token,但如果用户长时间未使用App,可能需要重新触发Sign-in流程。
  • CoroutineScope选择:绝对不要用GlobalScope,推荐使用viewModelScope(ViewModel中)或lifecycleScope(Activity/Fragment中),避免内存泄漏。
  • 消息确认:收到Pub/Sub消息后必须调用ackConsumer.ack(),否则消息会被重新投递。

内容的提问来源于stack exchange,提问作者Den

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:14:52