Page does hard refresh when session invalidated
Redsandro opened this issue · 27 comments
When token-refresh
fails, or is too late, or the session invalidates (automatically or manually), the page does a hard refresh. How do I stop this?
I still want to "change" my app, so an event would be nice, but I do not want a hard refresh. This is a SPA.
I'm using authenticator:jwt
and mistakenly posted an issue here: myartsev/ember-simple-auth-jwt#52
@Redsandro This library never does anything to cause a page refresh. Can you post the code needed to reproduce this behavior so I can take a look?
Triggering sessionDataInvalidated
causes a hard refresh for me. Here are my environment.js
settings:
ENV['ember-simple-auth-token'] = {
serverTokenEndpoint: `${ENV.APP.API}/token`,
serverTokenRefreshEndpoint: `${ENV.APP.API}/refresh`,
tokenExpirationInvalidateSession: true,
refreshAccessTokens: true,
refreshLeeway: 10, // 300,
}
When token-refresh fails (handleTokenRefreshFail
):
And when the session expires (handleAccessTokenExpiration
in the case of tokenExpirationInvalidateSession: true
):
This causes invalidationSucceeded
to be triggered upstream.
But I am not extending it. I don't know why the refresh happens.
@Redsandro Are you able to provide a complete example of this behavior? I can't reproduce the behavior with the information provided and I don't see anything that would cause this behavior. In all of my applications using this library, there is not a hard refresh when invalidationSucceeded
is triggered.
@fenichelar it's not easy because some code is not mine/libre, and I would need to spoof the backend and everything.
I will explore opinions from upstream first. If I can't get a hint as to what might cause this, I will go the extra miles. Although there has to be a way to listen for an event and track what triggered it.
In all of my applications using this library, there is not a hard refresh when
invalidationSucceeded
is triggered.
That's interesting, because I got word from upstream that:
Reloading is ESA's default behavior
How do your apps prevent it from happening?
Wait, just to be clear... are you using both TokenAuthorizerMixin
and ApplicationRouteMixin
?
Application adapter:
import TokenAuthorizerMixin from 'ember-simple-auth-token/mixins/token-authorizer'
Application router:
import ApplicationRouteMixin from 'ember-simple-auth/mixins/application-route-mixin'
On closer examination, I don't believe invalidationSucceeded
is actually being called in any of my applications.
I am using TokenAuthorizerMixin
but I am not using ApplicationRouteMixin
.
I take it back, I think invalidationSucceeded
is called it just doesn't do anything.
invalidationSucceeded
is called it just doesn't do anything.
Ah, okay, I get it. That's because you don't use the ApplicationRouteMixin
.
I think I might be using this wrong. I assumed I needed ApplicationRouteMixin
for handling the session and the automated refresh_token
business.
I only need TokenAuthorizerMixin
? It will handle the session refreshing? I can remove ember-simple-auth
? It's not a dependency/requirement?
Indeed, ApplicationRouteMixin
is optional. Do I even need to install ember-simple-auth
next to ember-simple-auth-token
, or can I remove it entirely?
(Btw, setting refreshAccessTokens
to false
does nothing, it will still refresh tokens.)
ember-simple-auth
is a required dependency of ember-simple-auth-token
. You don't need to manually install it or add it to your package.json
.
I just did a quick test with refreshAccessTokens
set to false
and it did not attempt to refresh the token. Can you show me your config?
ENV['ember-simple-auth-token'] = {
serverTokenEndpoint: `${ENV.APP.API}/token`,
serverTokenRefreshEndpoint: `${ENV.APP.API}/refresh`,
tokenExpirationInvalidateSession: true,
refreshAccessTokens: false,
refreshLeeway: 10, // 300,
}
JWT session expiration time is 15 seconds, and refreshLeeway 10, so that I only need to wait 5 seconds to test this out.
I can't seem to reproduce this, can you provide a working sample?
Closing. Let me know if you still have this issue.
It's doing this to me too. Somewhere in the code it's triggering a hard refresh and losing the token state.
This only happens locally for me.
I've tried just copying the local storage from my production app (as it's pointing to the same database) but that gets replaced immediately. No errors anywhere in the logs.
- What version of
ember-simple-auth-token
are you using? - What version of
ember-simple-auth
are you using? - What version of
ember
are you using? - Are you using either of the mixins?
- What is in your
ember-simple-auth-token
config? - Can you provide a sample app that can reproduce the hard refresh?
@fenichelar thank you so much for replying I really appreciate it.
- "ember-simple-auth": "^1.8.0",
- "ember-simple-auth-token": "^4.0.6",
-
ember: 3.15
- Using many many mixins but still using the classic object model including TokenAuthorizerMixin
'ember-simple-auth-token': {
serverTokenEndpoint: `${getHost(environment)}/auth/v1/login`,
refreshAccessTokens: false,
tokenExpireName: 'exp',
tokenExpirationInvalidateSession: true,
},
- This thing is a behemoth so not really but the repo is available here https://github.com/NYCPlanning/ceqr-app
What is mysterious to me is this behavior doesn't occur in production: https://www.ceqr.app.
Further context, I've inherited this app and am unsure how to proceed. I just cannot get it to authenticate. Attempts to cUrl the login endpoint in the backend work fine — they return the token. I can even observe a 200 OK response in the frontend. But I get a "transition aborted" — unless it's a red herring, it seems to be interrupting and I don't know why.
@allthesignals Thank you. I'm not completely following what the issue is. Can you walk through what is happening in a little more detail?
@allthesignals Thank you. I'm not completely following what the issue is. Can you walk through what is happening in a little more detail?
Yes, here's what I'm observing:
https://user-images.githubusercontent.com/5004319/116729040-ae651680-a9b4-11eb-9e8c-fc07927cf69e.mov
This is local development. When I successfully login (I am confirm through backend logs), it seems to try to transition to a new route, but does a hard refresh instead. This hard refresh causes the token to never be persisted in memory in the application instance.
This doesn't seem to occur in the production deployment of the site.
Even a vague guess at what is causing this would help...
Thank you!
Can you expend the transition aborted console log and provide the full output?
Can you expend the transition aborted console log and provide the full output?
Yes — I don't think it's very helpful though. I think something more serious is being buried... let me see if I have an error hook in a route somewhere:
"TransitionAborted: TransitionAborted
at logAbort (http://localhost:4200/assets/vendor.js:77099:12)
at PrivateRouter.transitionDidError (http://localhost:4200/assets/vendor.js:41243:44)
at http://localhost:4200/assets/vendor.js:76855:51
at invokeCallback (http://localhost:4200/assets/vendor.js:79339:17)
at publish (http://localhost:4200/assets/vendor.js:79322:9)
at publishRejection (http://localhost:4200/assets/vendor.js:79258:5)
at http://localhost:4200/assets/vendor.js:73757:53
at invokeWithOnError (http://localhost:4200/assets/vendor.js:72053:18)
at Queue.flush (http://localhost:4200/assets/vendor.js:71935:13)
at DeferredActionQueues.flush (http://localhost:4200/assets/vendor.js:72132:21)"
Ah, here's some more information (There indeed was an error hook swallowing up valuable information):
Okay, so the transitionAbort error might be happening because of an immediate 401:
Error: Ember Data Request GET http://localhost:3000/api/v1/projects returned a 401
Payload (application/json; charset=utf-8)
[object Object]
at ErrorClass.AdapterError (http://localhost:4200/assets/vendor.js:117431:29)
at new ErrorClass (http://localhost:4200/assets/vendor.js:117464:24)
at Class.handleResponse [as _super] (http://localhost:4200/assets/vendor.js:119364:18)
at Class.handleResponse (http://localhost:4200/assets/vendor.js:166925:19)
at Class.superWrapper [as handleResponse] (http://localhost:4200/assets/vendor.js:49590:22)
at ajaxError (http://localhost:4200/assets/vendor.js:119699:25)
at ajaxErrorHandler (http://localhost:4200/assets/vendor.js:119778:12)
at Class._hash.error (http://localhost:4200/assets/vendor.js:119467:25)
at fire (http://localhost:4200/assets/vendor.js:9519:31)
at Object.fireWith [as rejectWith] (http://localhost:4200/assets/vendor.js:9649:7)
So that invalidates something probably and causes a refresh or navigation to login? Looking at the XHR history is interesting:
What's odd about the "successful" login request is that it fails to load the response data?
I'm not sure if this is even how browsers behave, but perhaps there's some race condition.
EDIT:
Plot thickens... this.session.authenticate
throws the following:
TypeError: Cannot read property 'email' of undefined
at Class.sessionAuthenticated (labs-ceqr.js:20510)
at Class.superWrapper [as sessionAuthenticated] (vendor.js:49590)
at Class. (vendor.js:166708)
at sendEvent (vendor.js:31263)
at Class.trigger [as _super] (vendor.js:46377)
at Class.trigger (vendor.js:167293)
at Class.superWrapper [as trigger] (vendor.js:49590)
at Proxy. (vendor.js:167264)
at sendEvent (vendor.js:31263)
at Proxy.trigger (vendor.js:46377)
Can you expend the transition aborted console log and provide the full output?
You can disregard this now... I think this had to do with some weird dep resolutions issues for fetch (competing with jQuery maybe?) The particulars of the faulty fetch shim I was using were probably interfering with how ESA-token makes requests.
@allthesignals Is everything working now or just the transition?
@allthesignals Is everything working now or just the transition?
Everything is working now but my advice (or shot in the dark) for others would be to make sure there are no weird issues with ember-fetch. The fix described in that issue thread seemed to cause the issue. I got around it by switching to an earlier version of node.