AWS Cognito Identity Pool Логин и постоянство - PullRequest
0 голосов
/ 08 ноября 2018

Основная цель

Сохраните вход в систему с помощью пользовательских пулов Cognito и федеративных идентификаторов Cognito в приложении Android. Приложение должно обрабатывать обновление токенов (через SDK?). Электронная почта используется как имя пользователя. Разрешить только 1 уникальное имя пользователя (адрес электронной почты) во всем приложении. Пример: если пользователь входит в систему с Facebook с именем электронной почты / именем пользователя test@gmail.com, он не должен иметь возможность зарегистрировать пользователя через пулы пользователей с test@gmail.com*1008. *.

Настройка

У меня есть пул удостоверений, созданный с моими провайдерами аутентификации, такими как пул пользователей Cognito, Facebook и Google. Я использую нативные SDK для Facebook и Google для входа.

У меня есть SplashScreenActivity, которое проверяет, вошел ли пользователь в систему, и соответственно перенаправляет его (LoginActivity или MainActivity)

Использование моего пула пользователей с currentUser.getSession(authenticationHandler) прекрасно работает, если вход в систему осуществляется через пул пользователей.

Первый раз

  • Не авторизован
  • AuthenticationHandler: getAuthenticationDetails: userId is null
  • Показать LoginActivity

Логин

  • Вход через пул пользователей
  • Успех -> 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?

Окончательный Rant

Если вы когда-либо работали с Firebase Auth - ЭТО КАК Я ХОЧУ ПРИМЕНИТЬ К ФУНКЦИИ! Смехотворно легко настроить Firebase Auth с пользователями Firebase, входом в Facebook и входом в Google.

  • Войти с удостоверением личности
  • Передача токена в Firebase
  • Получить пользователя Firebase
  • Готово.

Хотите выйти? firebaseUser.logout (). Все просто.

Код

SplashScreenActivity

@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);
    }
};

LoginActivity

Я обрабатываю каждый сценарий входа в систему (пул пользователей, Facebook, Google)

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();
    }
}

1 Ответ

0 голосов
/ 10 ноября 2018

Новая AWSMobileClient, выпущенная как часть AWS Amplify Framework, может быть полезна здесь: https://aws -amplify.github.io / docs / android / authentication

У вас будут базовые возможности регистрации с пользовательскими пулами Cognito:

AWSMobileClient.getInstance().signUp()

Если вы настроили Identity Pools, он автоматически получит эти учетные данные. Все токены получают / обновляют / и т.д. обрабатывается автоматически. Вы также можете использовать Социальный вход:

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);
        });
...