gpt4 book ai didi

android - 如果帐户身份验证器中的身份验证 token 已过期,则使用刷新 token

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:45:04 25 4
gpt4 key购买 nike

我有一个应用程序使用 AccountManager 来存储用户的帐户。用户使用 OAuth2.0 密码-用户名凭据流程通过我的 REST API 登录和注册。

用户收到的access token在2小时后过期,需要刷新直到再次过期,以此类推。

我需要在我的身份验证器中实现这个刷新功能。

我有一个名为 AccessToken 的模型,它具有以下字段:

String accessToken、String tokenType、Long expiresIn、String refreshToken、String scope、Long createdAt

目前,在 AccountAuthenticator 类的 getAuthToken 方法中,我收到了这个 AccessToken 对象并使用它的 accessToken字段作为我的客户经理的 Auth Token

我需要的是使用我的客户经理以某种方式存储刷新 token 和授权 token ,以及当应用程序尝试访问 API 并获得错误响应时:{"error": "access token expired"},使用先前收到的 AccessToken 对象中的 refreshToken 字符串刷新当前访问 token 。但是,我不确定我应该怎么做。

我在 authenticator 类中的 getAuthToken 方法目前看起来是这样的:

@Override
public Bundle getAuthToken(AccountAuthenticatorResponse accountAuthenticatorResponse, Account account,
String authTokenType, Bundle options) throws NetworkErrorException {
if (!authTokenType.equals(AccountGeneral.AUTHTOKEN_TYPE_READ_ONLY) &&
!authTokenType.equals(AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS)) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ERROR_MESSAGE, "Invalid authTokenType");
return result;
}

final AccountManager manager = AccountManager.get(context.getApplicationContext());

String authToken = manager.peekAuthToken(account, authTokenType);

Log.d("Discounty", TAG + " > peekAuthToken returned - " + authToken);

if (TextUtils.isEmpty(authToken)) {
final String password = manager.getPassword(account);
if (password != null) {
try {
authToken = discountyService.getAccessToken(DiscountyService.ACCESS_GRANT_TYPE,
account.name, password).toBlocking().first().getAccessToken();
// =======
// Here the above discountyService.getAccessToken(...) call returns
// AccessToken object on which I call the .getAccessToken()
// getter which returns a string.
// =======
} catch (Exception e) {
e.printStackTrace();
}
}
}

if (!TextUtils.isEmpty(authToken)) {
final Bundle result = new Bundle();
result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
result.putString(AccountManager.KEY_AUTHTOKEN, authToken);
return result;
}

final Intent intent = new Intent(context, LoginActivity.class);
intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, accountAuthenticatorResponse);
intent.putExtra(LoginActivity.ARG_ACCOUNT_TYPE, account.type);
intent.putExtra(LoginActivity.ARG_AUTH_TYPE, authTokenType);
final Bundle bundle = new Bundle();
bundle.putParcelable(AccountManager.KEY_INTENT, intent);
return bundle;
}

AccountGeneral 类只包含一些常量:

public class AccountGeneral {

public static final String ACCOUNT_TYPE = "com.discounty";

public static final String ACCOUNT_NAME = "Discounty";

public static final String AUTHTOKEN_TYPE_READ_ONLY = "Read only";

public static final String AUTHTOKE_TYPE_READ_ONLY_LABEL = "Read only access to a Discounty account";

public static final String AUTHTOKEN_TYPE_FULL_ACCESS = "Full access";

public static final String AUTHTOKEN_TYPE_FULL_ACCESS_LABEL = "Full access to a Discounty account";
}

该应用程序还将使用 SyncAdapter 并将非常频繁地与 API 交互以同步来自和向服务器发送的数据,并且这些 API 调用还需要使用访问 token 作为参数请求,所以我真的需要实现这个刷新功能并使其自动化。


有人知道如何正确实现吗?


PS:我将使用本地数据库来存储我的所有数据,我也可以存储 token 对象。这似乎是一个简单的黑客攻击,虽然不安全。也许我应该每次只存储一个刷新 token 作为数据库记录,并在应用程序收到新 token 时更新它?

PPS:无论如何我都可以随意更改 API 的工作方式,因此如果有通​​过改进 API 来改进移动应用程序的建议,我们也非常感谢他们。

最佳答案

首次添加帐户时,您可以将刷新 token 保存到帐户的用户数据中:

Bundle userdata = new Bundle;
userdata.putString("refreshToken", refreshToken);
mAccountManager.addAccountExplicitly (account, password, userdata);

您也可以在添加账户后通过调用设置用户数据:

mAccountManager.setUserData(account, "refreshToken", refreshToken);

当您访问 token 过期时,您可以通过调用以下方式检索您的刷新 token :

String refreshToken = mAccountManager.getUserData(account, "refreshToken");

使用 refreshToken 检索新的访问 token 。

关于android - 如果帐户身份验证器中的身份验证 token 已过期,则使用刷新 token ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34528472/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com