AppAuth-Android无postLogoutRedirectUri时如何实现登出并关闭Chrome自定义标签
解决AppAuth Android端登出后自动关闭Chrome自定义标签页的问题
我刚好碰到过类似的场景,虽然你的IDP的discovery文档里没声明postLogoutRedirectUri,但我们可以通过手动指定本地重定向URI的方式,实现登出后自动关闭自定义标签页,下面是具体的实现步骤:
1. 完善LogoutRedirectUriReceiverActivity的Manifest配置
首先确保你的LogoutRedirectUriReceiverActivity能接收自定义的登出重定向URI,比如我们定义一个专属scheme(比如com.your.app://logout),在Manifest里添加对应的intent-filter:
<activity android:name=".LogoutRedirectUriReceiverActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- 这里的data要和后续指定的postLogoutRedirectUri完全匹配 --> <data android:scheme="com.your.app" android:host="logout" /> </intent-filter> </activity>
2. 手动构造登出请求并指定postLogoutRedirectUri
即使discoveryDoc里没有这个字段,AppAuth允许我们手动给登出请求添加该参数。构造EndSessionRequest时,直接设置我们刚才定义的本地URI:
// 假设你已持有AuthState实例和AuthorizationService实例 val authState: AuthState = ... val authorizationService: AuthorizationService = ... // 构建登出请求 val endSessionRequest = EndSessionRequest.Builder(authState.lastAuthorizationResponse!!.configuration) .setIdTokenHint(authState.idToken) // 手动指定本地重定向URI,触发我们的接收Activity .setPostLogoutRedirectUri(Uri.parse("com.your.app://logout")) .build() // 启动登出的Chrome自定义标签页 authorizationService.performEndSessionRequest( endSessionRequest, CustomTabsIntent.Builder().build(), object : AuthorizationService.EndSessionCallback { override fun onEndSessionCompleted(response: EndSessionResponse?, ex: AuthorizationException?) { // 清理本地状态:标记AuthState需要刷新、清空持久化的令牌等 authState.setNeedsTokenRefresh(true) saveAuthStateToLocal(authState) // 这里替换成你本地保存AuthState的逻辑 } } )
3. 在LogoutRedirectUriReceiverActivity中关闭标签页并结束自身
当IDP处理完登出后,会重定向到我们指定的com.your.app://logout,系统会自动启动这个Activity。我们只需要在onCreate里完成收尾:
class LogoutRedirectUriReceiverActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 让AppAuth处理登出回调,它会自动关闭对应的Chrome自定义标签页 val endSessionResponse = AuthorizationService.getEndSessionResponseFromIntent(intent) // 无论回调是否正常,直接结束Activity即可完成闭环 finish() } }
关键说明
- 很多IDP即使没在discovery文档里声明
postLogoutRedirectUri,实际上是支持这个参数的,所以手动指定完全可行。 - 这个方案的核心是通过本地重定向URI触发我们的Activity,借此获得关闭自定义标签页的时机——当标签页跳转到App时,系统会自动将其置于后台,我们再finish接收Activity,就能完成整个登出流程的闭环。
- 务必记得在登出回调里清理本地的
AuthState和持久化令牌,确保本地状态与服务器端保持一致。
内容的提问来源于stack exchange,提问作者Chief
相关产品推荐
相关产品推荐

