主要目标
通过在 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();
}
}