1

主要目标

通过在 Android 应用程序中使用 Cognito 用户池和 Cognito 联合身份来保持登录。应用程序应该处理令牌的刷新(通过 sdk?)。电子邮件用作用户名。在整个应用程序中只允许 1 个唯一的用户名(电子邮件)。示例:如果用户使用电子邮件/用户名test@gmail.com登录 Facebook ,他们应该无法通过test@gmail.com的用户池注册用户。

设置

我有一个身份池,我的身份验证提供者是我的 Cognito 用户池、Facebook 和 Google。我正在使用 Facebook 和 Google 的原生 SDK 登录。

我有一个 SplashScreenActivity 来检查用户是否已登录并相应地重定向它们(LoginActivity 或 MainActivity)

currentUser.getSession(authenticationHandler)如果通过用户池登录,使用我的用户池就可以了。

第一次

  • 未登录
  • AuthenticationHandler:getAuthenticationDetails:userId 为空
  • 显示登录活动

登录

  • 通过用户池登录
  • 成功 -> MainActivity

重启应用

  • AuthenticationHandler:onSuccess
  • 显示 MainActivity

如果我通过 facebook 登录并通过CognitoCachingCredentialsProvider它设置我的登录信息,它不会更新currentUser,所以我的getSession()电话不起作用。但是,我所能做的就是调用getCachedIdentityId(). 我的不会CognitoCachingCredentialsProvider过期吗?

此外,如果我使用从用户池创建的用户登录并注销 -currentUser.getUserId()使用我之前登录的用户池用户返回,但getCachedIdentityId()为空

private void logout() {
    EasyPrefs.clear(this); //clear shared preferences for local variables
    authHelper.getCredentialsProvider().clear(); //clear cached CognitoCredentialsProvider

    CognitoUser currentUser = AuthHelper.getInstance().getUserPool().getCurrentUser();
    currentUser.signOut(); //this is pointless if I login with federated identity

    //TODO: Logout of Google?
    //TODO: Logout of Facebook?

    //assume logout was successful?
    startActivity(new Intent(this, SplashScreenActivity.class));
    finish();
}

问题

  • 由于我正在使用用户池、facebook 和 google 处理本机登录 - 我是否必须手动管理访问令牌和刷新令牌?或者可以CognitoCachingCredentialsProvider帮我处理吗?
  • 我可以登录用户(通过用户池、facebook 或 google)并让他们保持登录状态吗?我该如何检查?
  • 当用户通过 facebook/google 登录时,我可以在我的用户池中本地创建用户吗

最后的咆哮

如果您曾经使用过 Firebase Auth - 这就是我希望应用程序发挥作用的方式!使用 Firebase 用户、Facebook 登录和 Google 登录来设置 Firebase Auth 非常容易。

  • 使用身份提供者登录
  • 将令牌传递给 Firebase
  • 获取 Firebase 用户
  • 完毕。

想要退出?firebaseUser.logout()。就那么简单。

代码

闪屏活动

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_splash_screen);

    authHelper = AuthHelper.getInstance();
    authHelper.init(this);

    //Check if a cached identity exists?
    //This will return an identity if user is user pool, facebook, google
    String cachedIdentityId = authHelper.getCredentialsProvider().getCachedIdentityId();
    Logger.d(TAG, cachedIdentityId == null ? "cachedIdentityId is null" : cachedIdentityId);

    //This is never null unless app data has been cleared?
    CognitoUser currentUser = authHelper.getUserPool().getCurrentUser();

    //Even if I call currentUser.signOut(), this still returns a userId
    String cachedUserId = currentUser.getUserId(); //because aws sucks
    Logger.d(TAG, cachedUserId == null ? "cachedUserId is null" : cachedUserId);

    //if user pool user is signed in, this will goto MainActivity
    currentUser.getSession(authenticationHandler);

    //not doing anything with cachedIdentityId because....?
}

private AuthenticationHandler authenticationHandler = new AuthenticationHandler() {
    @Override
    public void onSuccess(CognitoUserSession userSession, CognitoDevice newDevice) {
        startActivity(new Intent(SplashScreenActivity.this, MainActivity.class));
    }

    @Override
    public void getAuthenticationDetails(AuthenticationContinuation authenticationContinuation, String userId) {

        //wait a few seconds, then goto LoginActivity
        handler.postDelayed(timerTask, SECONDS * 2);
    }

    @Override
    public void getMFACode(MultiFactorAuthenticationContinuation continuation) {

    }

    @Override
    public void authenticationChallenge(ChallengeContinuation continuation) {

    }

    @Override
    public void onFailure(Exception exception) {
        Logger.e(TAG, AuthHelper.formatException(exception));

        //wait a few seconds, then goto LoginActivity
        handler.postDelayed(timerTask, SECONDS * 2);
    }
};

登录活动

我自己处理每个登录场景(用户池、Facebook、谷歌)

private void setLogins(String key, String token) {
    Map<String, String> logins = new HashMap<>();
    logins.put(key, token);
    authHelper.getCredentialsProvider().setLogins(logins);

    new RefreshCognitoCredentials().execute();
}

private class RefreshCognitoCredentials extends AsyncTask<Void, Void, String> {

    @SuppressLint("LongLogTag")
    @Override
    protected String doInBackground(Void... voids) {
        Map<String, String> logins = authHelper.getCredentialsProvider().getLogins();

        for(String key : logins.keySet()) {
            Logger.d(TAG, key + " - " + logins.get(key));
        }

        try {
            authHelper.getCredentialsProvider().refresh();
        } catch(NotAuthorizedException exception) {
            authHelper.getCredentialsProvider().clear();
            return null;
        }

        return authHelper.getCredentialsProvider().getIdentityId();
    }

    @SuppressLint("LongLogTag")
    @Override
    protected void onPostExecute(String response) {
        if(response == null) {
            Toast.makeText(getApplicationContext(), "Logins don't match. Please include at least one valid login for this identity or identity pool.", Toast.LENGTH_LONG).show();
            return;
        }

        Logger.d(TAG, response);
        startActivity(new Intent(AuthActivity.this, MainActivity.class));
        finish();
    }
}
4

1 回答 1

2

作为 AWS Amplify 框架的一部分发布的新AWSMobileClient功能可能会在这里提供帮助:https ://aws-amplify.github.io/docs/android/authentication

您将拥有 Cognito 用户池的基本注册功能:

AWSMobileClient.getInstance().signUp()

如果您已配置身份池,它将自动获取这些凭据。所有令牌获取/刷新/等。是自动处理的。您还可以使用社交登录:

AWSMobileClient.getInstance().federatedSignIn(
IdentityProviders.FACEBOOK.toString(), “FACEBOOK_TOKEN_HERE”, new Callback<UserState>() {
            @Override
            public void onResult(final UserState userState) {
                //Handle the result
            }

            @Override
            public void onError(Exception e) {
                Log.e(TAG, "sign-in error", e);
        });
于 2018-11-10T03:04:59.993 回答