witoldsz/angular-http-auth

no 'event:auth-loginRequired' since 1.3.0

javix opened this issue · 6 comments

javix commented

We have a problem with lines

 var bufferLength = httpBuffer.append(config, deferred);
 if (bufferLength === 1)
     $rootScope.$broadcast('event:auth-loginRequired', rejection);

The 'bufferLength' is always > 1, if used some resolves in route config and the user is not logged in.
In our case we use 4 resolve functions (rest calls to retrieving some data), they resulting in 401, because the user is not logged in before. The login dialog will be shown (OK). If the user enter wrong login data, the request results in 401, but the httpBuffer is not empty anymore and the event will not be thrown.

(sorry for grammatical errors)

That's surprising for me, because I would not close the login form until the password is OK (success) or the user has decided to give up (reject). Each case would clear the buffer...

javix commented

Some rest calls will be executed parallel during the login form is shown. They result of course is 401 because the user is not logged in and the httpBuffer length increaeses.
After the user has entered wrong login data the httpBuffer ist not empty and the event will not be thrown.

Let's clarify:

  • browser is sending requests, they all return as 401s,
  • first time the 401 comes, the event:auth-loginRequired is triggered,
  • the login section should now appear,
  • user is typing login, in the mean time more and more 401s are free to come,
  • user submits the form, but the login credentials are wrong, so the login section does not disappear, just the message about invalid credentials gets displayed,
  • user tries again and again and again,
  • finally the data are OK, so you hide the form, invoke authService.loginConfirmed() and all the 401s gets retried, or user surrenders and you invoke authService.loginCancelled() and all the 401s are abandoned or rejected.

How is your case different?

javix commented

We have the following scenario:

  • User open "host:8080/myapp/#/myroute" and was not logged in before.
  • The route 'myroute' is configured in RouteProviderConfig and has 3 resolve functions (see https://docs.angularjs.org/api/ngRoute/provider/$routeProvider).
  • angular try to resolve the route promises, they result status are 401, because the user was not logged in before.
  • here is the bufferLength = 3.
  • login dialog will be shown, because the promises return 401 and the event:auth-loginRequired is triggered by the first rest call.
  • user is typing wrong login data and confirm the dialog.
  • the LoginService on the backend will be called and returns 401.
  • the login dialog is still open.
  • if the login credentials are wrong, we expect the event:auth-loginRequired to show the message "Wrong logn data", but the event will not be triggered, because bufferLength > 1.

Our backend returns status 401 if the user is not logged in or if the user try to login with wrong login data.

I can see now. The thing is the login request itself should not go through the interceptor, because it's not something you would like store in buffer for retry later once user gets logged in. Especially that this is the request with invalid credentials, so why would you want it to be retried after successful login?

So, when user enters data you should set the request with ignoreAuthModule: true, so it's response will be ignored by the module and you will get the 401 response delivered directly to your controller. Based on what you get there you can display the right message.

P.S.
See the description in doc:
https://github.com/witoldsz/angular-http-auth#ignoring-the-401-interceptor

javix commented

Thanks, we changed our LoginService and it works now like expected.