Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auth state persistence #109

Closed
wants to merge 3 commits into from

Conversation

rlmartin
Copy link
Contributor

When using out-of-the-box withAuthenticator, the user authorization will not persist across sessions (i.e. when you reload the app). This commit adds persistence of the auth state across sessions, by using the sync method added to the react-native-aws-cognito-js library here: https://github.com/AirLabsTeam/react-native-aws-cognito-js/blob/master/src/StorageHelper.js#L71 (it uses the React Native AsyncStorage under the hood).

Please see the commit message for commentary on the second commit in this PR.

@rlmartin
Copy link
Contributor Author

This is my first PR on this project, so please tell me if I should be doing anything differently.

I looked for unit tests to add some, but couldn't find any in the aws-amplify-react-native package; point me to the right place and I can add some.

I considered adding a config option to the Auth class that would allow for turning off this feature, thus preserving the old behavior. I actually have a commit that it mostly done, but I decided to not add it to this PR because I couldn't tell if it was necessary, i.e. would anyone not want this feature? I also wasn't sure which the default should be: new feature 'on' by default (which I think is the expected behavior, for someone new to this library), or 'off' by default (which would not break the experience for current users). If there is a desire to be able to toggle this feature on/off, I can pretty easily add it as an option.

@codecov-io
Copy link

codecov-io commented Dec 29, 2017

Codecov Report

Merging #109 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master     #109   +/-   ##
=======================================
  Coverage   92.24%   92.24%           
=======================================
  Files          52       52           
  Lines        2424     2424           
  Branches      486      486           
=======================================
  Hits         2236     2236           
  Misses        179      179           
  Partials        9        9

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3c60b68...56d9e72. Read the comment docs.

@rlmartin rlmartin force-pushed the auth-state-persistence branch 2 times, most recently from d548fdf to 57cc599 Compare December 30, 2017 04:57
@thinusn
Copy link

thinusn commented Dec 30, 2017

Would be great if this was added.

return (this._userPoolStorageSync || Promise.resolve()).then(result => {
if (!that.userPool) { return Promise.reject('No userPool'); }

return that.userPool.getCurrentUser();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When retrieving the user from storage the signInUserSession field on the CognitoUser is null. Should _getSyncedUser() not set/refresh the session?
e.g.

const user = that.userPool.getCurrentUser();
if (!user) {
    return Promise.reject('No user');
}
return new Promise((resolve, reject) => {
    user.getSession((err, session) => {
        if (err) {
            reject(err);
        } else {
            user.setSignInUserSession(session)
            resolve(user);
        }
    });
});

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple thoughts.

First, it looks to me like signInUserSession gets assigned as part of the successful user.getSession call here: https://github.com/aws/aws-amplify/blob/923514dc42d1122642773ec5f00a7cd405d51c8b/packages/aws-amplify-react-native/src/lib/aws-cognito-identity/CognitoUser.js#L909. So unless I'm mistaken, I don't think we need the user.setSignInUserSession(session) line above.

Second - and here's where my unfamiliarity with this library's intricacies comes out - the existing code separates the concerns of getting the user from getting the user session. I specifically noticed that there are both currentUser and currentAuthenticatedUser methods - the latter of which loads the session, the former does not (current behavoir). Your suggestion would change this behavior, since I call_getSyncedUser() from both of these methods (plus a couple others). I believe that my commit as-is preserves current behavior - but feel free to correct me if I'm wrong. I think the session should be loaded into user.signInUserSession at the same time that it currently would be without this added feature of caching to AsyncStorage.

Are you seeing a particular example in which you are not seeing a populated user.signInUserSession when you would expect it to be populated? I can look into it if so.

@rlmartin
Copy link
Contributor Author

rlmartin commented Jan 7, 2018

@mlabieniec @powerful23 @nidsharm @richardzcode what is the process for getting a review? I don't think I've missed anything in CONTRIBUTING.md, but feel free to tell me if I did.

@mlabieniec
Copy link
Contributor

@rlmartin thanks again for the pr. Just fyi We are still working on this functionality, and just fyi, what we are doing is abstracting a lot of this stuff away from being react native specific, especially for things like auth. We want these things in the aws-amplify core to avoid duplication of code. So once we complete this task the core lib will handle the sessions and RN will naturally inherit the functionality using it's native storage.

This will maintain the auth state across sessions instead of losing
it when the app is refreshed.
This is necessary because Auth.currentUser() returns a Promise. When a
user is logged in and the app is reloaded, there is a brief flicker
during which the SignIn screen is shown before the authenticated app
appears. This Loading screen replaces that flicker and will toggle to
either signIn or signedIn, as appropriate.
@mlabieniec
Copy link
Contributor

This logic has been merged into aws-amplify core and is now available in react native. This will be in the next publish to npm.

@mlabieniec mlabieniec closed this Jan 31, 2018
@Darkade
Copy link

Darkade commented Feb 2, 2018

@mlabieniec next publish means now with v0.2.0 or later? I'm just looking for this in the documentation or code.

Thanks

@mlabieniec
Copy link
Contributor

@Darkade Yes that is correct. So now, unless you are using HOCs / components i.e. Authenticator you can just use aws-amplify within react native, and you need to use aws-amplify to initially configure. Basically rn is the same as aws-amplify-react now.

@github-actions
Copy link

This pull request has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants