morpheus05 morpheus05 - 10 months ago 82
Android Question

Implement oauth code exchange from provider to my web server

I'd like to implement oauth2 login for multiple clients: [may be Java Script,] Desktop and Android.

What I'd like my clients to do is to use the native browser for showing the user the consent screen (e.g. google).
If the user agrees, the provider should send back the oauth code back to the client and the client should send this code to my REST Server which then performs the actual code<->token exchange. My server will then generate a JWT and send this back to my client.

  • The clients never see a oauth token

  • They do not contain any kind of client_secrets

For the android app to work this way, I would have to create a "Web Client" in the google dev console with a special redirect url. This approach is suggested in this guide.
The problem is now, that the google dev console doesn't allow this. You only can specify HTTP and HTTPS URLs.

My question is: How can I implement a flow, where a code is send back to my android app and the app sends the code to my server which performs the code<->token exchange?

Answer Source

I solved my problem the following way:

  1. In the google dev console I added a Web Client as an application. The reaseon I used a Web Client and not an Android Application was simple: I couldn't register a redirect URI in the Console for Android applications. If I use a standard android oauth solution the access token is send to the android application which I don't want: I want the access token inside my REST server and not the individual clients. Thats why my Android app should send the code back to the REST server

  2. For the redirect uri to work, you have to construct a URL with a custom scheme. Google will only accept custom schemes which are the reverse of your client Id. So for example, if your clientId is then reverse is As a final redirect URI I registered: Note: The single /!

  3. In the AndroidManifest I registered an Activity with a specific intent filter:

    <activity android:name=".OAuthAccessTokenActivity" android:launchMode="singleTask">>
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="" />

Pay attention to the <data> declaration: No host or path is specified here, only the scheme.

  1. In an UI (game or something) show a google Login Button which will open a WebView or Chrome Custom Tab. I would recommand Google Chrome Custom Tab because it is much nicer for the user then WebView. (Example FitBit prohibits WebView for the auth Page) The Chrome Custom Tab solution looks something like this:

     CustomTabsClient.bindCustomTabsService(activity.applicationContext,"", object : CustomTabsServiceConnection() {
      override fun onCustomTabsServiceConnected(name: ComponentName, client: CustomTabsClient) {
        val session = client.newSession(object : CustomTabsCallback() {  })
        session.mayLaunchUrl(Uri.parse(""), null, null)
      override fun onServiceDisconnected(name: ComponentName) {
        // client is no longer valid. This also invalidates sessions.
      val authorizationUrl =    "
      val builder = CustomTabsIntent.Builder()
      val customTabsIntent =
      customTabsIntent.launchUrl(activity, Uri.parse(authorizationUrl))

At the time of writting, its not possible to detect which URL the Tab currently displays, thats why we have to register our own Activity for our custom scheme. The redirect of the Tab will tell Android top open the registered Activity for our custom scheme.

  1. Inside the activity Send the code back to your server which can now exchange the code for an access token: class OAuthAccessTokenActivity :Activity() { .... val url = val code = url.getQueryParameter("code") .... }