【问题标题】:CognitoCachingCredentialsProvider getCachedIdentityId is null after app close and re-open应用关闭并重新打开后,CognitoCachingCredentialsProvider getCachedIdentityId 为 null
【发布时间】:2015-02-02 14:10:48
【问题描述】:

我可能误解了此方法的预期行为,但这是我尝试使用它的目的:

-用户登录成功 -用户完全关闭应用程序(也在后台关闭) - 用户再次打开应用程序并且不必再次登录,因为 CognitoCachingCredentialsProvider 可以在设备上本地检查以查看她是否仍处于登录状态

我尝试完成此操作的方法是在提示登录之前检查 getCachedIdentityId() 返回的内容。如果它返回非空值,则意味着她仍在登录,因为没有任何东西可以从设备中清除她的凭据。这是我的框架的样子。我正在使用开发者认证的方法:

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;

import com.amazonaws.auth.AWSAbstractCognitoIdentityProvider;
import com.amazonaws.auth.CognitoCachingCredentialsProvider;
import com.amazonaws.mobileconnectors.cognito.*;
import com.amazonaws.regions.Regions;

public class Util {
    private final static String TAG = "Util";

    private static final String AWS_ACCOUNT_ID = {acct id};
    private static final String COGNITO_POOL_ID = {pool id};
    private static final String COGNITO_ROLE_AUTH = {auth arn};
    private static final String COGNITO_ROLE_UNAUTH = {unauth arn}

    private static CognitoCachingCredentialsProvider sCredProvider;
    private static UserIdentityProvider sIdProvider;
    private static CognitoSyncManager sSyncManager;

    private Util() {
    }

    public static CognitoCachingCredentialsProvider getCredProvider(
            Context context) {
    if (sCredProvider == null) {
        if (sIdProvider == null) {
            CognitoCachingCredentialsProvider tmpProvider = new CognitoCachingCredentialsProvider(
                    context.getApplicationContext(), AWS_ACCOUNT_ID,
                    COGNITO_POOL_ID, COGNITO_ROLE_UNAUTH,
                    COGNITO_ROLE_AUTH, Regions.US_EAST_1);
            if (tmpProvider.getCachedIdentityId() != null) {
                sCredProvider = tmpProvider;
            } else {
                sCredProvider = null;
            }
        } else {
            sCredProvider = new CognitoCachingCredentialsProvider(
                    context.getApplicationContext(), sIdProvider,
                    COGNITO_ROLE_UNAUTH, COGNITO_ROLE_AUTH);
            Map logins = new HashMap();
            logins.put({Developer Provider Name}, sIdProvider.getToken());
            sCredProvider.setLogins(logins);
        }
    }
    return sCredProvider;
    }

    public static UserIdentityProvider getIdentityProvider(Context context,
            String email, String pwd) {
        if (sIdProvider == null) {
            sIdProvider = new UserIdentityProvider(AWS_ACCOUNT_ID,
                COGNITO_POOL_ID, context.getApplicationContext());
        }
        return sIdProvider;
    }

    public static boolean isLoggedIn(Context context) {
        if (getCredProvider(context) == null) {
            return false;
        }
        return true;
    }

    protected static class UserIdentityProvider extends
            AWSAbstractCognitoIdentityProvider {

        private Context context;
        private String email;
        private String password;

        public UserIdentityProvider(String accountId, String identityPoolId,
                Context c) {
            super(accountId, identityPoolId);
            context = c;
            email = em;
            password = pwd;
        }

        @Override
        public String refresh() {
            try {
                ServerCommunicator server = new ServerCommunicator(context);
                if (email != null && password != null) {
  //this is a server call, which makes the call GetOpenIdTokenForDeveloperIdentityRequest after I authenticate the user and send AWS my user's token
                    String response = server.initUserLoginAsyncTask()
                            .execute(email, password).get();
                    prefs.setAllUserSharedPrefs(response);
                    JSONObject responseJSON = new JSONObject(response);
                    String identityId = responseJSON.getString("id");
                    String token = responseJSON.getString("token");
                    if (token != null && identityId != null) {
                        this.setToken(token);
                        this.setIdentityId(identityId);
                        update(identityId, token);
                        return token;
                }
            }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        public String getProviderName() {
            return {Developer Provider Name};
        }

    }

} 

我只是从这个类中调用 isLoggedIn 方法来查看本地是否存储了 IdentityId。但是,这并没有按预期工作。我可以从调试中看到 getCachedIdentityId 始终为空(即使在初始化 CognitoCachingCredentialsProvider 并将令牌添加到登录映射之后也是如此),并且每当我在关闭应用程序后打开应用程序时,总是提示我再次登录。 IdentityId 什么时候实际存储在本地,我的逻辑总体上是否正确?

附加代码

import java.util.concurrent.ExecutionException;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends Activity {

private final String TAG = "LoginActivity";

private EditText etEmail, etPwd;
private Button bLogin, bGoToRegister;
private ServerCommunicator server;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i(TAG, "onCreate");
    server = new ServerCommunicator(this);
    if (Util.isLoggedIn(this)) {
        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        return;
    }
    this.setContentView(R.layout.activity_login);
    etEmail = (EditText) findViewById(R.id.etEmail);
    etPwd = (EditText) findViewById(R.id.etPassword);
    bLogin = (Button) findViewById(R.id.bLogin);
    bGoToRegister = (Button) findViewById(R.id.bGoToRegister);
    bLogin.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            String email = etEmail.getText().toString();
            String pwd = etPwd.getText().toString();
            Util.getIdentityProvider(v.getContext()).setEmail(email);
            Util.getIdentityProvider(v.getContext()).setPassword(pwd);
            String token = Util.getIdentityProvider(v.getContext()).refresh();
            if (token != null) { 
                Intent intent = new Intent(v.getContext(), MainActivity.class); 
                startActivity(intent);
            }  else {
                 Toast.makeText(v.getContext(), "Invalid username/password",
                 Toast.LENGTH_SHORT).show();
            }
        }
    });
}
}

以上是我的 LoginActivity。当应用程序启动 MainActivity 时,我的 onCreate 方法开头有以下 sn-p:

if (!Util.isLoggedIn(this)) {
        Intent intent = new Intent(this, LoginActivity.class);
        startActivity(intent);
}

此调用初始化 CognitoCachingCredentialsProvider。我假设这将是 IdentityId 被缓存的时候,但我的调试显示即使在这个块之后,getCachedIdentityId() 仍然返回 null。我是如何尝试使用此类的吗?

【问题讨论】:

  • 你能提供更多的代码上下文吗?具体来说,相对于这个生命周期,您的身份提供者在哪里调用刷新?
  • @JeffBailey 嗨,感谢您的关注。使用附加代码查看我的编辑。让我知道我是否应该提供其他任何信息来帮助进一步澄清这一点。

标签: amazon-web-services amazon-cognito


【解决方案1】:

我有一个建议。 CognitoCachingCredentialsProvider 是在 identityId 更改时保存它。但是,它不会开始侦听,直到它被初始化,并且更改发生在对您的身份提供者的刷新调用时。

您能否尝试将 CognitoCachingCredentialsProvider 的初始化移到刷新调用之前(但在您的身份提供者初始化之后)?

编辑:

Update 将设置 identityId 和 token,但是事先进行的显式调用可能会导致它认为没有进行任何更改。您是否也可以尝试消除 setter 调用?

【讨论】:

  • 我想这就是你的意思:Util.getIdentityProvider(v.getContext()).setEmail(email); Util.getIdentityProvider(v.getContext()).setPassword(pwd); Util.getCredProvider(v.getContext());字符串令牌 = Util.getIdentityProvider(v.getContext()).refresh(); ...但这没有用。我不认为这应该重要。如果我设置了登录名,那么我认为这就是缓存 id 的原因。关于如何完成我想要完成的工作还有其他想法吗?
  • 是的,我在之前的评论中描述的编辑应该会执行您的建议。前两行静态初始化我的身份提供者。然后我初始化 Credentials Provider,然后我在 Identity Provider 上调用 refresh。这是你的意思吗?它也没有做我想做的事情。
  • 你是什么意思,这不是你想要做的?此外,缓存 id 仅在捕获身份更改事件时发生,并且该事件的侦听器仅在您拥有已初始化的凭据提供程序后才被初始化。基本上,这应该很重要。
  • 您能否确认您在初次登录时获得了身份 ID?
  • 我只是想缩小问题的范围。如果您最初获得一个 identityId,那确实有助于做到这一点。您可以尝试消除对 setToken 和 setIdentityId 的调用吗?更新将处理这些,由于已经设置了这些,它可能不会触发侦听器。
猜你喜欢
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多