简体   繁体   English

Android、AccountManager 和 OAuth

[英]Android, AccountManager and OAuth

I'm sure this is basic and I'm missing something.我确定这是基本的,我错过了一些东西。 I've read through other answers on SO, I've googled, I've read resources and I just can't wrap my head around what I need to do.我已经阅读了关于 SO 的其他答案,我已经用谷歌搜索过,我已经阅读了资源,但我无法理解我需要做什么。

I'm trying to figure out how to write an app that connects to Twitch's API, specifically how to authenticate with Twitch's api.我试图弄清楚如何编写一个连接到 Twitch 的 API 的应用程序,特别是如何使用 Twitch 的 API 进行身份验证。 Their documentation is here: https://github.com/justintv/Twitch-API/blob/master/authentication.md他们的文档在这里: https : //github.com/justintv/Twitch-API/blob/master/authentication.md

I've created an app and stored my keys.我创建了一个应用程序并存储了我的密钥。

Now comes the part where I want my user to click a button which launches the authentication on their website.现在是我希望我的用户单击一个按钮在他们的网站上启动身份验证的部分。 From what I can tell I do this by using an AccountManager.据我所知,我是通过使用 AccountManager 来做到这一点的。 Except... I can't figure out what I'm supposed to do.除了......我不知道我应该做什么。

Here's the excerpt I've found online:这是我在网上找到的摘录:

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

According to twitch's documentation I want to send the user to:根据 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]

And I simply have no idea how these two things need to be combined.我根本不知道这两个东西需要如何结合。

Firstly, I recommend to read the OAuth2 RFC .首先,我建议阅读OAuth2 RFC This should cover everything you need to know.这应该涵盖您需要知道的一切。

The AccountManager code snippet won't help you much unless there already is an app that provides authentication for Twitch.除非已经有一个应用程序为 Twitch 提供身份验证,否则 AccountManager 代码片段不会对您有多大帮助。 If that's not the case you either need to use an existing OAuth2 library or implement your own.如果不是这种情况,您要么需要使用现有的 OAuth2 库,要么实现您自己的库。 You could write your own AccountAuthenticator but that's a different challenge (and you still need some kind of OAuth2 client).您可以编写自己的AccountAuthenticator但这是一个不同的挑战(您仍然需要某种 OAuth2 客户端)。

Doing it yourself is not that hard, see below.自己做并不难,见下文。

Steps to implement it yourself自己实现的步骤

Twitch recommends to use the "Implicit Grant Flow" for mobile apps. Twitch 建议对移动应用程序使用“隐式授权流程”。 That's what I'm going to describe below.这就是我将在下面描述的内容。

1. Get a client ID 1.获取客户端ID

Register your app as outlined in Developer Setup to get a client ID按照开发人员设置中的说明注册您的应用以获取客户端 ID

As redirect URI you can use something like https://localhost:12398/ , the actual port doesn't really matter.作为redirect URI您可以使用类似https://localhost:12398/ ,实际端口并不重要。

2. Build the authentication URL 2.构建认证网址

In your client app you need to construct the authentication URL like so:在您的客户端应用程序中,您需要像这样构造身份验证 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]

Apparently [your client ID] should be replaced by the client ID you've received from Twitch, same goes for [your registered redirect URI] (that's the URL above, ie https://localhost:12398/ ).显然, [your client ID]应该替换为您从 Twitch 收到的客户端 ID,同样适用于[your registered redirect URI] (即上面的 URL,即https://localhost:12398/ )。 [space separated list of scopes] is the list of scopes (ie features your want to access), see Scopes . [space separated list of scopes][space separated list of scopes]列表(即您要访问的功能),请参阅Scopes Make sure you URL-encode the parameter values properly.确保正确对参数值进行 URL 编码。

Assuming your client ID is 123456 and the scopes you need are user_read and channel_read your URL would look like this:假设您的客户端 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

Note that you should also pass a state parameter, just use a randomly generated value.请注意,您还应该传递一个state参数,只需使用随机生成的值。 You can also append the (non-standard) force_verify parameter to make sure the user actually needs to log in each time (instead of continuing a previous session), but I think you can achieve the same by clearing the cookie store (given that you open the URL in a webview in the context of your app) before you open the login page.您还可以附加(非标准) force_verify 参数以确保用户实际上每次都需要登录(而不是继续上一个会话),但我认为您可以通过清除 cookie 存储来实现相同的目的(假设您在您打开登录页面之前,在您的应用程序上下文中的 web 视图中打开 URL。

With a random state the URL would look like this:在随机状态下,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

Again, make sure the state value is properly URL encoded.再次确保状态值是正确的 URL 编码。

3. Open the authentication URL 3.打开认证网址

Ideally you just open the URL in a WebView inside of your app.理想情况下,您只需在应用程序内的WebView打开 URL。 In that case you need to intercept all request to load a new URL using WebViewClient.shouldOverrideUrlLoading在这种情况下,您需要使用WebViewClient.shouldOverrideUrlLoading拦截所有加载新 URL 的请求

Once the client is redirected to your redirect URL you can close the webview and continue with step 4.将客户端重定向到您的redirect URL您可以关闭 web 视图并继续执行步骤 4。

Theoretically it's possible to utilize the default browser to do the authentication, but I would have security concerns since an external app could learn about your client ID and the access token.理论上可以使用默认浏览器进行身份验证,但我会有安全问题,因为外部应用程序可以了解您的客户端 ID 和访问令牌。

4. Extract the access token 4. 提取访问令牌

The actual URL you get redirected to in step #3 will have the form:您在第 3 步中重定向到的实际 URL 将具有以下形式:

https://[your registered redirect URI]/#access_token=[an access token]&scope=[authorized scopes]

or to pick up the example或者拿起例子

https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read

Where xxx is the actual access token.其中xxx是实际的访问令牌。

If you passed a state it will be present like so:如果您通过了一个state ,它将显示如下:

https://localhost:12398/#access_token=xxx&scope=user_read%20channel_read&state=82hdknaizuVBfd9847guHUIhndzhuehnb

All you have to do now is to parse the (URL encoded) access token, scope and state.您现在要做的就是解析(URL 编码的)访问令牌、范围和状态。 Compare the scopes and state to the ones that you actually sent.将范围和状态与您实际发送的范围和状态进行比较。 If they match you can start using the access_token to authenticate.如果它们匹配,您可以开始使用 access_token 进行身份验证。

Note According to the OAuth2 RFC, the response URL MUST also contain a token_type and it SHOULD contain an expires_in duration in seconds.注意根据 OAuth2 RFC,响应 URL 还必须包含一个token_type并且它应该包含一个expires_in持续时间(以秒为单位)。

Once you received the access token you can use it to authenticate as described here .一旦你获得访问令牌,你可以用它来描述验证这里

Access tokens issued by the Implicit Grant Flow usually expire after a certain time and the user needs to authenticate again.由隐式授予流程颁发的访问令牌通常会在一定时间后过期,用户需要再次进行身份验证。 The Twitch documentation doesn't mention any expiration time, so it's possible that the token is valid forever. Twitch 文档没有提到任何过期时间,因此令牌可能永远有效。 So make sure your app doesn't store it or store it in a secure way (like using Android's key store provider to generate and store a key to encrypt the access token).因此,请确保您的应用不会存储它或以安全的方式存储它(例如使用Android 的密钥存储提供程序来生成和存储密钥以加密访问令牌)。

If the implicitly issued access token expires you could consider using the "Authorization Code Flow".如果隐式颁发的访问令牌过期,您可以考虑使用“授权代码流”。 That's quite similar but it contains an additional step to receive the access token and a "refresh token" that can be used to renew the access token.这非常相似,但它包含一个额外的步骤来接收访问令牌和可用于更新访问令牌的“刷新令牌”。 I leave it up to you to figure out how that works.我把它留给你来弄清楚它是如何工作的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用Android AccountManager获取OAuth2令牌? - Obtain OAuth2 token using android AccountManager? 自己的AccountManager和OAuth2 - Own AccountManager and OAuth2 Android AccountManager.getUserData() 返回 null - Android AccountManager.getUserData() returns null 使用Android的AccountManager添加自定义帐户 - Adding a custom account using Android's AccountManager 您是否应该使用AccountManager存储Android应用的用户名和密码? - Should you use AccountManager for storing Usernames and Passwords for an Android app? Android AccountManager抛出AuthenticatorException:添加帐户时绑定失败 - Android AccountManager throws AuthenticatorException: bind failure when adding account 如何在具有Google帐户的Android中使用AccountManager? - How can I use AccountManager in Android with Google Account? 是否有使用AccountManager帐户在Android上对Google Data API进行身份验证的官方方法? - Is there an official way to authenticate for Google Data API on Android using AccountManager accounts? 受信任的 Web 活动 [TWA] - 它可以读取 Android 上的 AccountManager 帐户吗? - Trusted Web Activity [TWA] - Can it read AccountManager accounts on Android? com.google.gdata.client.GoogleService.setUserToken(android.accounts.AccountManager.getAuthToken(???)) - com.google.gdata.client.GoogleService.setUserToken(android.accounts.AccountManager.getAuthToken(???))
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM