Skip to content
This repository has been archived by the owner on Oct 24, 2024. It is now read-only.

authState.isPending is true after logout #887

Open
2 tasks done
patkovskyi opened this issue Sep 1, 2020 · 17 comments
Open
2 tasks done

authState.isPending is true after logout #887

patkovskyi opened this issue Sep 1, 2020 · 17 comments

Comments

@patkovskyi
Copy link

patkovskyi commented Sep 1, 2020

I'm submitting this issue for the package(s):

  • okta-react

I'm submitting a:

  • Bug report

Current behavior

authState.isPending is true after calling authService.logout()
Screenshot 2020-09-01 at 18 49 56

This seems wrong to me since it breaks this official example:

const { authState, authService } = useOktaAuth();
 if (authState.isPending) {
   return <div>Loading...</div>;
 }

Expected behavior

All fields of authState are set to null after logout.

Minimal reproduction of the problem with instructions

On https://github.com/okta/samples-js-react (custom-login)

@shuowu:
go to login page, then click back button directly without login.

Not the scenario I initially described, but probably has the same root cause (isPending == true when it should not be).

Extra information about the use case/user story you are trying to implement

Essentially, this is what happens: when a user initiates logout, the first authState change the app is receiving looks like the screenshot (all fields are null, isPending is true). After that, most of the time there is another authState update with isPending == false (I don't know what triggers it). But sometimes it does not happen and users observe "Loading..." indefinitely. In any case, I can verify with a debugger that the first update to authState after logout always contains isPending == true which seems to be a bug.

Environment

  • Package Version: 3.0.4
  • Browser: Chrome 86.0.4240.8
  • OS: MacOS Catalina 10.15.6
  • Node version (node -v): v12.18.3
@shuowu
Copy link
Contributor

shuowu commented Sep 1, 2020

@patkovskyi isPending is set to true (the default state) by design when logout happens, as a success logout will do a hard reload to refresh the memory, then the client will re-evaluate the authState to set isPending to either true or false.

But sometimes it does not happen and users observe "Loading..." indefinitely.

This may be caused by a logout failure, then the authState failed to be updated properly.

I think it would make sense to update authState.error if logout fails.

Internal Ref: OKTA-326953

@patkovskyi
Copy link
Author

@shuowu thanks for taking a look!

I find the meaning of isPending quite confusing. My initial expectation was that it means: authentication flow is currently running. But there's no ongoing authentication flow after logout.

I encountered two cases when having isPending set to true by design consistently breaks a React app:

  1. onbeforeunload event was intercepted and a user chose not to leave the page after authService.logout() was executed. I guess hard reload you're mentioning does not happen in this case.
  2. when I'm not logged in and navigate via back button to the /login route which contains this code:
const { authState, authService } = useOktaAuth();
if (authState.isPending) {
  return <div>Loading...</div>;
}

isPending is true but the authentication process does not trigger so the page just stays in "Loading..."

@swiftone
Copy link
Contributor

swiftone commented Sep 1, 2020

My initial expectation was that it means: authentication flow is currently running

@patkovskyi - Close, but not quite. isPending means "We are currently figuring out what your authorization is". This can be waiting on an async currently-running authorization flow, but it could also be waiting on an async retrieval of tokens (such as IndexedDB).

Authorization state is decided by checking tokens, tokens MAY be stored in an async way, so knowing if you are authorized is async until it is decided, and until that is decided you are 'pending'.

That's why on initial load, the auth state is pending, and if you aren't authenticated, it will stop being pending and become false - the async token check returned, and you weren't authenticated.

@patkovskyi
Copy link
Author

@swiftone thanks for clarification!

So, is there anything I can do to make okta-react figure out the real authentication state after I use back button (more details in my previous message)?

@shuowu
Copy link
Contributor

shuowu commented Sep 1, 2020

@patkovskyi

onbeforeunload event was intercepted and a user chose not to leave the page after authService.logout() was executed.

The hard reload is not only to clear the memory, but also redirect to logout uri to clear user session from backend, then redirect user back based on the logoutRedirectUrl, which means this process should not be interrupted with onbeforeunload listener.

when I'm not logged in and navigate via back button to the /login route which contains this code

The sdk evaluated the authState based on the tokens state when the route changes in app. So I don't think any action is needed from the app code. Or do you see issues with navigate back by the back button?

@patkovskyi
Copy link
Author

@shuowu

When I click Back after a full successful logout, it brings me to /login route where isAuthenticated == false, isPending == true, tokens are undefined and nothing else happens.

@patkovskyi
Copy link
Author

patkovskyi commented Sep 2, 2020

Here's a video repro for the Back button issue: https://www.dropbox.com/s/t6xrm5adozxpswp/Screen%20Recording%202020-09-01%20at%2021.00.03.mov
I show the whole flow: Login -> Logout -> clicking Back (around 00:55)

@shuowu
Copy link
Contributor

shuowu commented Sep 2, 2020

@patkovskyi Thanks for the video, I am able to reproduce the issue locally now.

Internal Ref: OKTA-327283

@patkovskyi
Copy link
Author

patkovskyi commented Sep 2, 2020

@shuowu

I was unable to reproduce this issue on samples-js-react custom-login, even after I changed okta-react version from 3.0.0 to 3.0.4. I'm curious how you reproduced it, maybe it points to some specific thing in my code that triggers this issue.

Meanwhile, I think I found a dirty workaround: adding authState.isAuthenticated === null condition fixes the problem in my repro video.

const { authState, authService } = useOktaAuth();
if (authState.isPending && authState.isAuthenticated === null) {
  return <div>Loading...</div>;
}

return authState.isAuthenticated
    ? <Redirect to={{ pathname: Routes.root }} />
    : <SignInWidget />;

@shuowu
Copy link
Contributor

shuowu commented Sep 2, 2020

@patkovskyi go to login page, then click back button directly without login.

@sero323
Copy link

sero323 commented Sep 22, 2020

Having the same issue. Any fixes in the works?

@lee-bennie
Copy link

I'm also having this issue. At 3.0.8, isPending is true after having logged out, and stays true. Downgrading to 3.0.0 produces expected results, where isPending is true until isAuthenticated is false.

@swiftone
Copy link
Contributor

swiftone commented Oct 9, 2020

@sero323 & @lee-bennie: We do not have a solution at this time, but the team is reviewing priorities today and I'll see if we can get this bumped up.

Meanwhile, can you clarify if this is happening every time on logout, most times, or occasionally? (original report was "most of the time it works")

Also, can you detail what steps your app takes on logout to see if anything is different from the other report?

@lee-bennie
Copy link

@sero323 & @lee-bennie: We do not have a solution at this time, but the team is reviewing priorities today and I'll see if we can get this bumped up.

Meanwhile, can you clarify if this is happening every time on logout, most times, or occasionally? (original report was "most of the time it works")

Also, can you detail what steps your app takes on logout to see if anything is different from the other report?

In my case I'm really just treating "after logout" as a blank slate, so if my issue doesn't belong here, let me know. But I've narrowed the change down to v3.0.4.

So at <= 3.0.3, when with when I look at the state of Security, I can see:
{ _authState: { isAuthenticated: false, idToken: undefined, accessToken: undefined } }

and then at >= 3.0.4:

{ _authState: { isAuthenticated: false, idToken: undefined, accessToken: undefined, isPending: true } }

These are with clean application storage, so no cookies, no local or session storage. Clean install of node modules.

authParams: { responseType: ['id_token', 'token'], scopes: ['openid', 'email', 'profile'], pkce: true, }

@sero323
Copy link

sero323 commented Jan 13, 2021

Any progress on this issue?

@swiftone
Copy link
Contributor

@sero323 - This should be corrected in okta-react 3.0.9+, see https://github.com/okta/okta-react/releases/tag/okta-react-3.0.9.

Let us know if you continue to see this problem.

@lee-bennie
Copy link

@sero323 I can confirm that 3.0.9 fixed it for me.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants