Reputation: 11
I am new to Angular and implementing authentication for users.
Most of suggestions on the web propose to save session/username in local storage and when user is back to the app, check local storage in order to display proper navigation (in my navbar I have different nav buttons for private and public views).
However, I found this solution having some drawbacks. For example, if session on server expired, or local storage was manually added, then when app will be initialising, it will show wrong buttons in navbar.
After that I came to solution - to use service before showing navbar buttons, to send request to server to verify if user from local storage with his session is currently active. And only after that I will display nav buttons.
Here comes a question: is it the most efficient way to proof check if user from local storage is logged in and session is active?
There is another way, which I was thinking, but didn't find solution. Since my angular webapp and nodejs server are located in two different places, is it possible for the webapp to check authentication status (make a request from webapp server to my nodejs server) when index.html is requested and respond with pre-rendered navbar and user status (logged in or not)?
Thanks.
P.S. I am using PassportJS and Express on server side.
Upvotes: 1
Views: 3154
Reputation: 11
To have navbar showing different elements for authenticated and non-authenticated users, one of possible solutions will be
authentication.service.ts
, which will have trigger every time an event of the result of checking authorisation of current user...
interface ShareObj { [id: string]: any; }
...
currentUserId: ShareObj = {};
currentUserUsername: ShareObj = {};
public authenticatedBehavior = new ReplaySubject(1);
authCheck(): any {
return this.http.get('/api/auth-check')
.map((resp: any) => {
if (resp.authanticated) {
this.currentUserId['global'] = resp.user.id;
this.currentUserUsername['global'] = resp.user.username;
this.authenticatedBehavior.next(true);
} else {
this.authenticatedBehavior.next(false);
this.currentUserId['global'] = null;
this.currentUserUsername['global'] = null;
}
return resp;
})
.catch(e => {
this.authenticatedBehavior.next(false);
this.currentUserId['global'] = null;
this.currentUserUsername['global'] = null;
});
}
So, in navbar.component.ts
there should be a listener for this event:
ngOnInit() {
this.authService.authenticatedBehavior
.subscribe(
data => {
// do change of UI of navbar depending if user logged in or not
}
);
}
error-iterceptor.ts
file, where you should "catch" all failed requests and check them for Unauthorised
response (401). If you catch such response, do authCheck()
in authentication.service.ts
to make sure that session of current user expired and notify all components which listen for authenticatedBehavior
Upvotes: 0
Reputation: 5719
The best practise is to use AuthGuard
and implement CanActivate
to check whether user can view a particular part of the application. Also an authentication service is used normally to let the user login to system and gain an access token.
This access token is then used as Authorisation-Header
on each request to server (this is where they will be in sync).
You will need to check for JWT/or any other type
token on load which contains user information plus session time out.
If the token is invalid you simply redirect the user to login, otherwise it will allow user to go where they wanted to.
A practical example can be found here.
Upvotes: 1