Reputation: 31970
I know this has been asked countless times, but none of the answers I found described the actual connection to backend.
I have a one-page JS app that communicates with small backend (Django) API. I use session based authentication. User info is cached on first load. If session expires, I need to change page header and flush user info from cache. However, most of my API resources are public and return always 200. Several other resources are private and return 403 if user isn't logged in, which is great as this gives me excatly the information I need. The problem is, some pages access public resources only. In case session is suddenly deleted on backend and user navigates to url that accesses only public resources, user info isn't flushed and I have an UX problem.
My initial idea was to request private user resource (let's call it /users/self/
) on every url change which returns 200 in case user is authenticated and 403 in case they aren't. This however requires 1 extra request before every other request for each url change, which isn't really ideal.
Are there any easier techniques I could use in this case? I don't mind even switching to other type of authentication if that would solve the problem.
Upvotes: 5
Views: 390
Reputation: 3221
We at work do what others have already told you: use an HttpInterceptor.
We have every response sent from our backend structured in the same way: an object with two fields: a responseCode and the actual response. We vary the responseCode according to what happened in the backend, being success, security alert, or authentication required for that given action the most common cases.
Then the interceptor reacts in the appropriate way according to each responseCode we have defined. In the case of an authentication required, we redirect to the login page, you could do whatever you need. It's working great for us.
Upvotes: 1
Reputation: 26848
Your backend could add a header to the response if the user is still logged in, regardless if the requested resource is public or not. The client can then check the presence of that header and act accordingly.
On both sides this is done with some kind of filter or interceptor. In angular this would be a $http interceptor.
Upvotes: 1
Reputation: 8646
Instead of sending a additional auth request, just check in your backend in every request, if the session didnt expire. If the user is not auth, then return a status code.
In angularjs we used a httpResponse interceptor, who intercepts every response and checks against this status code.
Upvotes: 1
Reputation: 42669
What i have done and seen for such scenarios is to use some type of http interceptor that intercept all http requests done by Angular and if it finds a response status of 401, such interceptors raise an event using $rootScope
.
See one library here https://github.com/witoldsz/angular-http-auth
To use it, one needs to subscribe to the events raise using some type of root controller, which can redirect the user to login page.
See an example here https://medium.com/opinionated-angularjs/7bbf0346acec
Upvotes: 2