Android端集成Google登录时如何获取accessToken发送至后端
解决方案
新版Google Identity Services SDK默认不会在GoogleSignInAccount中直接返回accessToken,需要先在登录配置中添加服务端授权参数,再通过返回的授权码兑换accessToken。更安全的做法是将授权码交给后端完成兑换,避免密钥在客户端泄露。
步骤1:修改Google登录初始化配置
构造GoogleSignInOptions时需要额外添加服务端客户端ID参数,以及你后端需要的接口权限scope:
// 注意:此处的SERVER_CLIENT_ID是Google Cloud控制台中创建的**Web类型**客户端ID,不是安卓端的客户端ID val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) .requestEmail() // 按需添加后端需要的OAuth scope,比如请求Google日历权限就加"https://www.googleapis.com/auth/calendar" .requestScopes(Scope("https://www.googleapis.com/auth/userinfo.profile")) .requestServerAuthCode(SERVER_CLIENT_ID, false) // 第二个参数设为true代表强制返回刷新令牌,按需设置 .build() val googleSignInClient = GoogleSignIn.getClient(context, gso)
步骤2:在登录成功回调中获取授权码,传给后端兑换accessToken
private fun handleGoogleSignInResult(task: Task<GoogleSignInAccount>) { task.addOnSuccessListener { googleSignInAccount -> // 获取服务端授权码 val authCode = googleSignInAccount.serverAuthCode if (authCode != null) { // 直接将authCode传给你的后端接口,由后端调用Google OAuth接口兑换accessToken、refreshToken sendAuthCodeToBackend(authCode) } } task.addOnFailureListener { e -> Timber.e(e) showToast(R.string.something_went_wrong_try_again_later) } }
可选:客户端直接兑换accessToken(不推荐)
如果确实需要在客户端直接获取accessToken,可以使用GoogleAuthorizationCodeTokenRequest发起请求兑换:
// 注意:该方式需要在客户端存储服务端密钥,存在泄露风险,仅建议测试阶段使用 CoroutineScope(Dispatchers.IO).launch { try { val tokenResponse = GoogleAuthorizationCodeTokenRequest( NetHttpTransport(), JacksonFactory.getDefaultInstance(), "https://oauth2.googleapis.com/token", SERVER_CLIENT_ID, SERVER_CLIENT_SECRET, // 服务端客户端对应的密钥,Google Cloud控制台可获取 authCode, "" // 重定向URI,Web端用的,安卓端留空即可 ).execute() val accessToken = tokenResponse.accessToken val refreshToken = tokenResponse.refreshToken // 后续处理逻辑 } catch (e: Exception) { e.printStackTrace() } }
注意事项
- 必须确保
SERVER_CLIENT_ID和你的安卓应用在同一个Google Cloud项目下 - 申请的scope需要和后端要调用的Google接口权限对应,否则兑换出的accessToken无法正常使用
内容的提问来源于stack exchange,提问作者Ahmed Bakhet
相关产品推荐
相关产品推荐

