Android、AccountManager 和 OAuth

Tri*_*ett 4 java api android oauth accountmanager

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

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

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

现在是我希望我的用户单击一个按钮在他们的网站上启动身份验证的部分。据我所知,我是通过使用 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
Run Code Online (Sandbox Code Playgroud)

根据 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]
Run Code Online (Sandbox Code Playgroud)

我根本不知道这两个东西需要如何结合。

Mar*_*ten 5

首先,我建议阅读OAuth2 RFC。这应该涵盖您需要知道的一切。

除非已经有一个应用程序为 Twitch 提供身份验证,否则 AccountManager 代码片段不会对您有多大帮助。如果不是这种情况,您要么需要使用现有的 OAuth2 库,要么实现您自己的库。您可以自己编写,AccountAuthenticator但这是一个不同的挑战(您仍然需要某种 OAuth2 客户端)。

自己做并不难,见下文。

自己实现的步骤

Twitch 建议对移动应用程序使用“隐式授权流程”。这就是我将在下面描述的内容。

1.获取客户端ID

按照开发人员设置中的说明注册您的应用以获取客户端 ID

由于redirect URI您可以使用类似的东西https://localhost:12398/,实际的端口并不重要。

2.构建认证网址

在您的客户端应用程序中,您需要像这样构造身份验证 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]
Run Code Online (Sandbox Code Playgroud)

显然[your client ID]应该替换为您从 Twitch 收到的客户端 ID,同样适用[your registered redirect URI](即上面的 URL,即https://localhost:12398/)。[space separated list of scopes]是范围列表(即您想要访问的功能),请参阅Scopes。确保正确对参数值进行 URL 编码。

假设您的客户端 ID123456和您需要的范围是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
Run Code Online (Sandbox Code Playgroud)

请注意,您还应该传递一个state参数,只需使用随机生成的值。您还可以附加(非标准) force_verify 参数以确保用户实际上每次都需要登录(而不是继续上一个会话),但我认为您可以通过清除 cookie 存储来实现相同的目的(假设您在您打开登录页面之前,在您的应用程序上下文中的 web 视图中打开 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
Run Code Online (Sandbox Code Playgroud)

再次确保状态值是正确的 URL 编码。

3.打开认证网址

理想情况下,您只需在WebView应用程序内部打开 URL 。在这种情况下,您需要拦截所有请求以使用WebViewClient.shouldOverrideUrlLoading

一旦客户端被重定向到你的,redirect URL你可以关闭 webview 并继续第 4 步。

理论上可以使用默认浏览器进行身份验证,但我会有安全问题,因为外部应用程序可以了解您的客户端 ID 和访问令牌。

4. 提取访问令牌

您在第 3 步中重定向到的实际 URL 将具有以下形式:

https://[your registered redirect URI]/#access_token=[an access token]&scope=[authorized scopes]
Run Code Online (Sandbox Code Playgroud)

或者拿起例子

https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read
Run Code Online (Sandbox Code Playgroud)

xxx实际访问令牌在哪里。

如果你通过了,state它会像这样出现:

https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read&state=82hdknaizuVBfd9847guHUIhndzhuehnb
Run Code Online (Sandbox Code Playgroud)

您现在要做的就是解析(URL 编码的)访问令牌、范围和状态。将范围和状态与您实际发送的范围和状态进行比较。如果它们匹配,您可以开始使用 access_token 进行身份验证。

注意根据 OAuth2 RFC,响应 URL 还必须包含 atoken_type并且它应该包含expires_in以秒为单位的持续时间。

一旦你获得访问令牌,你可以用它来描述验证这里

由隐式授予流程颁发的访问令牌通常会在一定时间后过期,用户需要再次进行身份验证。Twitch 文档没有提到任何过期时间,因此令牌可能永远有效。因此,请确保您的应用程序不会存储它或以安全的方式存储它(例如使用Android 的密钥存储提供程序生成和存储密钥以加密访问令牌)。

如果隐式颁发的访问令牌过期,您可以考虑使用“授权代码流”。这非常相似,但它包含一个额外的步骤来接收访问令牌和可用于更新访问令牌的“刷新令牌”。我把它留给你来弄清楚它是如何工作的。