java - Android、AccountManager 和 OAuth

标签 java android api oauth accountmanager

我确定这是基本的,我错过了一些东西。我已经阅读了关于 SO 的其他答案,我用谷歌搜索过,我已经阅读了资源,但我无法理解我需要做的事情。

我试图弄清楚如何编写一个连接到 Twitch 的 API 的应用程序,特别是如何使用 Twitch 的 api 进行身份验证。他们的文档在这里:https://github.com/justintv/Twitch-API/blob/master/authentication.md

我创建了一个应用程序并存储了我的 key 。

现在是我希望我的用户单击在其网站上启动身份验证的按钮的部分。据我所知,我是通过使用 AccountManager 来做到这一点的。除了... 我不知道我应该做什么。

这是我在网上找到的摘录:

AccountManager am = AccountManager.get(this);
        Bundle options = new Bundle();

        am.getAuthToken(
                myAccount_,                     // Account retrieved using getAccountsByType()
                "Manage your tasks",            // Auth scope
                options,                        // Authenticator-specific options
                this,                           // Your activity
                new OnTokenAcquired(),          // Callback called when a token is successfully acquired
                new Handler(new OnError()));    // Callback called if an error occurs

根据 twitch 的文档,我想将用户发送到:
https://api.twitch.tv/kraken/oauth2/authorize
    ?response_type=code
    &client_id=[your client ID]
    &redirect_uri=[your registered redirect URI]
    &scope=[space separated list of scopes]
    &state=[your provided unique token]

而且我根本不知道如何将这两件事结合起来。

最佳答案

首先,我建议阅读 OAuth2 RFC 。这应该涵盖您需要知道的所有内容。
AccountManager 代码 fragment 对您没有多大帮助,除非已经有一个为 Twitch 提供身份验证的应用程序。如果不是这种情况,您要么需要使用现有的 OAuth2 库,要么实现自己的。
您可以编写自己的 AccountAuthenticator ,但这是一个不同的挑战(您仍然需要某种 OAuth2 客户端)。
自己做并不难,见下文。
自己实现的步骤
Twitch 建议对移动应用程序使用“隐式授权流程”。这就是我将在下面描述的内容。
1.获取客户端ID
按照 Developer Setup 中的说明注册您的应用程序以获取客户端 ID
作为 redirect URI 您可以使用类似 https://localhost:12398/ 的东西,实际端口并不重要。
2.构建认证URL
在您的客户端应用程序中,您需要像这样构造身份验证 URL:

https://api.twitch.tv/kraken/oauth2/authorize?
    response_type=token&
    client_id=[your client ID]&
    redirect_uri=[your registered redirect URI]&
    scope=[space separated list of scopes]
显然 [your client ID] 应该替换为您从 Twitch 收到的客户端 ID,[your registered redirect URI] 也是如此(即上面的 URL,即 https://localhost:12398/ )。 [space separated list of scopes] 是范围列表(即您想要访问的功能),请参阅 Scopes 。确保正确地对参数值进行 URL 编码。
假设您的客户端 ID 是 123456 并且您需要的范围是 user_readchannel_read 您的 URL 将如下所示:
https://api.twitch.tv/kraken/oauth2/authorize?
    response_type=token&
    client_id=123456&
    redirect_uri=https%3A%2F%2Flocalhost%3A12398%2F&
    scope=user_read%20channel_read
请注意,您还应该传递一个 state 参数,只需使用随机生成的值。您还可以附加(非标准) force_verify 参数以确保用户每次确实需要登录(而不是继续前一个 session ),但我认为您可以通过清除 cookie 存储来实现相同的目的(假设您在您打开登录页面之前,在您的应用程序上下文中的 web View 中打开 URL)。
在随机状态下,URL 将如下所示:
https://api.twitch.tv/kraken/oauth2/authorize?
    response_type=token&
    client_id=123456&
    redirect_uri=https%3A%2F%2Flocalhost%3A12398%2F&
    scope=user_read%20channel_read&
    state=82hdknaizuVBfd9847guHUIhndzhuehnb
同样,确保状态值是正确的 URL 编码的。
3.打开认证网址
理想情况下,您只需在应用程序内的 WebView 中打开 URL。在这种情况下,您需要拦截所有请求以使用 WebViewClient.shouldOverrideUrlLoading 加载新 URL
将客户端重定向到您的 redirect URL 后,您可以关闭 web View 并继续执行第 4 步。
理论上可以使用默认浏览器进行身份验证,但我会担心安全问题,因为外部应用程序可以了解您的客户端 ID 和访问 token 。
4.提取访问 token
您在步骤 #3 中被重定向到的实际 URL 将具有以下形式:
https://[your registered redirect URI]/#access_token=[an access token]&scope=[authorized scopes]
或者举个例子
https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read
其中 xxx 是实际的访问 token 。
如果你传递了一个 state 它将像这样出现:
https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read&state=82hdknaizuVBfd9847guHUIhndzhuehnb
您现在要做的就是解析(URL 编码的)访问 token 、范围和状态。将范围和状态与您实际发送的范围和状态进行比较。如果它们匹配,您可以开始使用 access_token 进行身份验证。
注意 根据 OAuth2 RFC,响应 URL 还必须包含一个 token_type 并且它应该包含一个以秒为单位的 expires_in 持续时间。
收到访问 token 后,您可以使用它进行身份验证,如 here 所述。
Implicit Grant Flow 颁发的访问 token 通常会在一定时间后过期,用户需要再次进行身份验证。 Twitch 文档没有提及任何到期时间,因此 token 可能永远有效。因此,请确保您的应用程序不存储它或以安全的方式存储它(例如使用 Android's key store provider 生成和存储 key 以加密访问 token )。
如果隐式发布的访问 token 过期,您可以考虑使用“授权代码流程”。这非常相似,但它包含一个额外的步骤来接收访问 token 和可用于更新访问 token 的“刷新 token ”。我让你来弄清楚它是如何工作的。

关于java - Android、AccountManager 和 OAuth,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36562174/

相关文章:

java - 有多少个可调用对象?

java - 添加新条目后如何刷新 JTable

java - FlatMap 与 Filter、Map Java

java - Android - 进度条不更新

android - 在 Kotlin 构造函数中向参数添加 private 修饰符有什么区别?

java - 如何在响应对象中设置状态码400

java - Jaxb - 如何将一个 xml 元素解码到多个字段?

Java:如何从不基于键的 HashMap 中正确删除值

facebook - 获取其他 Facebook 用户 IP 地址的最佳方式

android - 如何从 ESHA Research API 调用多个营养信息? (apid.esha.com)