实现从提供程序到我的Web服务器

时间:2016-09-12 20:41:31

标签: android oauth

我想为多个客户端实现oauth2登录:[可能是Java脚本,]桌面和Android。

我希望我的客户要做的是使用本机浏览器向用户显示同意屏幕(例如谷歌)。 如果用户同意,提供者应该将oauth代码发送回客户端,并且客户端应该将此代码发送到我的REST服务器,然后REST服务器执行实际的代码< - >令牌交换。然后我的服务器将生成一个JWT并将其发送回我的客户端。

  • 客户端永远不会看到oauth令牌
  • 它们不包含任何类型的client_secrets

为了让android应用程序以这种方式工作,我必须在google开发者控制台中使用特殊的重定向URL创建一个“Web客户端”。 this guide中建议采用此方法。 问题是,谷歌开发者控制台不允许这样做。您只能指定HTTP和HTTPS URL。

我的问题是:我如何实现一个流程,将代码发送回我的A​​ndroid应用程序,然后应用程序将代码发送到执行代码< - >令牌交换的服务器?

1 个答案:

答案 0 :(得分:0)

我通过以下方式解决了我的问题:

  1. 在google开发者控制台中,我添加了一个Web客户端作为应用程序。该 reaseon我使用的是Web客户端而不是Android应用程序很简单:我 无法在Android应用程序的控制台中注册重定向URI。 如果我使用标准的android oauth解决方案,访问令牌将被发送到我不想要的Android应用程序:我想在我的REST服务器内部访问令牌,而不是个人客户端。这就是为什么我的Android应用程序应该将代码发送回REST服务器

  2. 要使重定向uri起作用,您必须使用自定义方案构造一个URL。 Google只会接受与您相反的自定义方案 客户ID。例如,如果您的clientId是XXX.apps.googleusercontent.com,那么反向就是 apps.googleusercontent.com.XXX。作为我注册的最终重定向URI: apps.googleusercontent.com.XXX:/oauth2Callback。注意:单/!

  3. 在AndroidManifest中,我注册了一个具有特定意图的活动 过滤器:

    <activity android:name=".OAuthAccessTokenActivity" android:launchMode="singleTask">>
        <intent-filter>
            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
            <data android:scheme="apps.googleusercontent.com.XXX" />
        </intent-filter>
    </activity>
    
  4. 注意<data>声明:此处未指定主机或路径,仅指定方案。

    1. 在用户界面(游戏或其他)中显示一个谷歌登录按钮,它将打开一个 WebView或Chrome Custom Tab。我建议使用Google Chrome自定义标签 因为它对用户来说比WebView更好。 (示例FitBit prohibits WebView for the auth Page) Chrome自定义标签解决方案如下所示:

       CustomTabsClient.bindCustomTabsService(activity.applicationContext,"com.android.chrome", object : CustomTabsServiceConnection() {
      
        override fun onCustomTabsServiceConnected(name: ComponentName, client: CustomTabsClient) {
          client.warmup(0)
          val session = client.newSession(object : CustomTabsCallback() {  })
      
          session.mayLaunchUrl(Uri.parse("https://accounts.google.com/o/oauth2/v2/auth"), null, null)
        }
      
        override fun onServiceDisconnected(name: ComponentName) {
          // client is no longer valid. This also invalidates sessions.
        }
      })
      
        val authorizationUrl =    "https://accounts.google.com/o/oauth2/v2/auth?scope=YOURSCOPEURL&state=&redirect_uri=YOUR_REDIRECT_URI&response_type=code&client_id=CLIENT_ID
        val builder = CustomTabsIntent.Builder()
        val customTabsIntent = builder.build()
      
        customTabsIntent.launchUrl(activity, Uri.parse(authorizationUrl))
      
    2. 在写入时,无法检测Tab的哪个URL 目前显示,这就是为什么我们必须为我们注册我们自己的活动 自定义方案。选项卡的重定向将告诉Android顶部打开我们的自定义方案的注册活动。

      1. 活动内部 将代码发送回您的服务器,现在可以交换代码 访问令牌: class OAuthAccessTokenActivity :Activity() { .... val url = intent.data val code = url.getQueryParameter("code") .... }