1

我正在编写一个简单的 Android 应用程序,它目前提供以下功能:

  1. 使用电子邮件和密码注册/登录,针对AWS Cognito后端
  2. 注销(针对相同的 Cognito 后端)
  3. 在AWS API Gateway上调用受保护的 Web API

我正在构建自己非常简单的登录/注销 UI,而不是使用 AWS Cognito UI 库:

登录和登录屏幕

登录屏幕(左);登录画面(右)

当用户登录时,Web API 应返回 200(和正文),并在用户注销时返回 403 错误。服务器设置似乎都是正确的,iOS 上的等效应用程序按描述工作。

Android上的问题如下:

  • 当我启动应用程序时,不要登录并调用 API:我收到 403 错误(预期)。
  • 当我登录并再次调用 API 时:我仍然收到 403 错误(意外)。
  • 当我关闭应用程序时,从最近的应用程序列表中滑动它,然后重新打开它:我仍然登录(预期)
  • 现在,当我调用 API 时:我收到 200 响应(预期)。

如果我注销现在也会发生同样的情况:注销后我仍然收到 200 响应,直到我终止应用程序并重新启动它。

如何在不回收应用程序的情况下立即获得 API 网关调用以尊重我当前的身份验证状态?

我想知道是否应该归咎于 AWS API Gateway Android 库,所以我尝试了使用OkHttp的替代实现,但我得到了完全相同的结果。我的 Cognito 代码基于AmazonCognitoYourUserPools 演示

这是我的 build.gradle 中导入 AWS 库的部分:

// AWS Mobile Client
implementation('com.amazonaws:aws-android-sdk-mobile-client:2.6.18@aar') { transitive = true }

// Cognito UserPools for SignIn
implementation 'com.android.support:support-v4:27.1.1'
implementation('com.amazonaws:aws-android-sdk-auth-userpools:2.6.18@aar') { transitive = true }

// AWS API gateway
implementation 'com.amazonaws:aws-android-sdk-apigateway-core:2.6.18'

在此处粘贴大量代码可能无济于事,但我已经为所涉及的主要类创建了要点(删除了日志记录等,以使它们尽可能小且相关):

AwsInterceptor中引用的类ApiCaller.java来自这里

4

2 回答 2

2

我和我的同事得出的解决方案如下:

登录

AWSMobileClient登录后,您需要在调用任何 API 网关端点之前重新初始化。AuthenticationHandler这是我的片段LoginActivity.java

private AuthenticationHandler authenticationHandler = new AuthenticationHandler()
{
    @Override
    public void onSuccess(final CognitoUserSession userSession,
                          final CognitoDevice newDevice)
    {
        // Initialise the client again
        AWSMobileClient.getInstance().initialize(LoginActivity.this, new AWSStartupHandler()
        {
            @Override
            public void onComplete(final AWSStartupResult awsStartupResult)
            {
                switchTo(LoggedInActivity.class);
            }
        }).execute();
    }

    // ...
}

登出

注销后,我们发现需要从IdentityManager. 这个片段来自我的LoggedInActivity.java

private void logout()
{
    final CognitoUser currentUser = getCurrentUser();
    currentUser.signOut();

    // Clear the IdentityManager credentials
    final IdentityManager idm = new IdentityManager(this, new AWSConfiguration(this));
    IdentityManager.setDefaultIdentityManager(idm);
    idm.getUnderlyingProvider().clearCredentials();
    idm.getUnderlyingProvider().clear();
    idm.getUnderlyingProvider().setLogins(null);

    switchTo(LoginActivity.class);
}
于 2018-04-24T14:17:03.973 回答
1

如何在不回收应用程序的情况下立即获得 API 网关调用以尊重我当前的身份验证状态?

AWSMobileClient每次在ApiCaller.java中调用 AWS API 时尝试初始化

import com.amazonaws.mobile.client.AWSMobileClient;
import com.amazonaws.mobile.client.AWSStartupHandler;
import com.amazonaws.mobile.client.AWSStartupResult;

AWSMobileClient.getInstance().initialize(this, new AWSStartupHandler() {
    @Override
    public void onComplete(AWSStartupResult awsStartupResult) {
        final AWSCredentialsProvider credentialsProvider = AWSMobileClient.getInstance().getCredentialsProvider();
        // .....

    }
}).execute();

根据我对 AWS Android 的有限经验,我认为这是确保客户端准备就绪的方法

于 2018-04-19T13:10:34.953 回答