Основная цель
Сохраните вход в систему с помощью пользовательских пулов 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();
}
}