简体   繁体   English

AWS Cognito身份池登录和持久性

[英]AWS Cognito Identity Pool Login and Persistence

Primary Objective 主要目标

Persist login through the use of Cognito User Pools and Cognito Federated Identities in an Android app. 通过在Android应用中使用Cognito用户池和Cognito联合身份来持久登录。 The app should handle refresh of tokens (via the sdk?). 该应用程序应处理令牌刷新(通过SDK?)。 Email is used as username. 电子邮件用作用户名。 Only allow 1 unique username (email) throughout entire application. 在整个应用程序中仅允许使用1个唯一的用户名(电子邮件)。 Example: If a user logs in with Facebook with an email/username of test@gmail.com , they should not be able to register a user through user pools with test@gmail.com . 示例:如果用户以电子邮件/用户名test@gmail.com登录到Facebook,则他们应该不能通过用户池通过test@gmail.com注册用户。

Setup 设定

I have an Identity Pool created with my Authentication Providers being my Cognito User Pool, Facebook, and Google. 我创建了一个身份库,身份验证提供者是我的Cognito用户池,Facebook和Google。 I am using the native SDK's for Facebook and Google to sign in. 我正在使用适用于Facebook和Google的本地SDK进行登录。

I have a SplashScreenActivity that checks to see if a user is logged in and redirects them accordingly (LoginActivity or MainActivity) 我有一个SplashScreenActivity,它检查用户是否已登录并相应地重定向他们(LoginActivity或MainActivity)

Using my user pool with currentUser.getSession(authenticationHandler) works just fine, if logged in via the user pool. 如果通过用户池登录,则将我的用户池与currentUser.getSession(authenticationHandler)一起使用会很好。

First Time 第一次

  • Not logged in 未登录
  • AuthenticationHandler:getAuthenticationDetails:userId is null AuthenticationHandler:getAuthenticationDetails:userId为null
  • Show LoginActivity 显示登录活动

Login 登录

  • Login via User Pool 通过用户池登录
  • Success -> MainActivity 成功-> MainActivity

Restart App 重新启动应用

  • AuthenticationHandler:onSuccess 的AuthenticationHandler:的onSuccess
  • Show MainActivity 显示MainActivity

If I log in via facebook and set my logins via the CognitoCachingCredentialsProvider it doesn't update currentUser , so my getSession() call doesn't work. 如果我通过Facebook登录并通过CognitoCachingCredentialsProvider设置登录名,则不会更新currentUser ,因此我的getSession()调用不起作用。 However, all I can then do is call getCachedIdentityId() . 但是,我所能做的就是调用getCachedIdentityId() Doesn't my CognitoCachingCredentialsProvider expire? 我的CognitoCachingCredentialsProvider不会过期吗?

Furthermore if I login with a user created from a User Pool and logout - currentUser.getUserId() returns with my previously logged in user pool user, but getCachedIdentityId() is null 此外,如果我使用从用户池创建的用户登录并注销currentUser.getUserId()与我先前登录的用户池用户getCachedIdentityId()返回,但getCachedIdentityId()为null

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

Questions 问题

  • Since I am handling native login with user pool, facebook, and google - do I have to manage access tokens and refresh tokens manually? 由于我正在使用用户池,facebook和google处理本机登录,我是否必须手动管理访问令牌并刷新令牌? Or can the CognitoCachingCredentialsProvider handle that for me? 还是CognitoCachingCredentialsProvider可以为我处理此问题?
  • Can I login a user (via user pool, facebook, or google) and have them stayed logged in and how do I check? 我可以(通过用户池,facebook或google)登录用户并保持登录状态,如何检查?
  • Can I natively create a user in my user pool when a user logs in via facebook/google? 当用户通过facebook / google登录时,是否可以在用户池中本地创建用户?

Final Rant 最终狂乱

If you have ever worked with Firebase Auth - THIS IS HOW I WANT THE APPLICATION TO FUNCTION! 如果您曾经使用过Firebase Auth-这就是我想要该功能的应用程序! It is ridiculously easy to setup Firebase Auth with Firebase Users, Facebook login, and Google login. 使用Firebase用户,Facebook登录名和Google登录名设置Firebase Auth非常容易。

  • Login with identity provider 用身份提供商登录
  • Pass token to Firebase 将令牌传递给Firebase
  • Get a Firebase User 获取Firebase用户
  • Done. 完成。

Want to logout? 要注销? firebaseUser.logout(). firebaseUser.logout()。 Simple as that. 就那么简单。

Code

SplashScreenActivity 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 LoginActivity

I handle each login scenario natively (user pool, facebook, google) 我本机处理每个登录方案(用户池,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();
    }
}

The new AWSMobileClient that has been released as part of the AWS Amplify Framework might be of assistance here: https://aws-amplify.github.io/docs/android/authentication 作为AWS Amplify框架的一部分发布的新AWSMobileClient在这里可能会有所帮助: https : AWSMobileClient

You will have basic Sign Up capabilities with Cognito User Pools: 您将具有Cognito用户池的基本注册功能:

AWSMobileClient.getInstance().signUp()

If you've configured Identity Pools it will automatically get those credentials. 如果配置了身份池,它将自动获取这些凭据。 All token fetch/refresh/etc. 所有令牌获取/刷新/等。 is handled automatically. 是自动处理的。 You can also use Social sign in: 您还可以使用社交登录:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM