I am developing an Angular application with Spring boot. I have developed a login page that takes username and password as input. A web service which authenticates the user from the backend and sends a response with success and failure. And a homepage that gets displayed after successful authentication.
What's happening is that I can also open the home page URL directly without login and that's not the correct one.
What I need is to implement a mechanism that will checks if the user is logged in or not and based on that it would display a URL page or a login page.
One of the best practices to handle authentication in web applications is using JWT to generate and check Token on the server side and passing token in the communications of Front-end & back-and. When you implement this and after authentication in server, you have to store Token in LocalStorage or SessionStorage or cockies for future interactions.
For creating protected routes in Angular application you have to implement these:
Here is a sample code for you:
app-AuthGuard.ts
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { AuthenticationService } from '@app/_services';
@Injectable({ providedIn: 'root' })
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private authenticationService: AuthenticationService
) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const currentUser = this.authenticationService.currentUserValue;
if (currentUser) {
// check if route is restricted by role
if (route.data.roles && route.data.roles.indexOf(currentUser.role) === -1) {
// role not authorised so redirect to home page
this.router.navigate(['/']);
return false;
}
// authorised so return true
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
return false;
}
}
auth.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '@environments/environment';
import { User } from '@app/_models';
@Injectable({ providedIn: 'root' })
export class UserService {
constructor(private http: HttpClient) { }
getAll() {
return this.http.get<User[]>(`${environment.apiUrl}/users`);
}
getById(id: number) {
return this.http.get<User>(`${environment.apiUrl}/users/${id}`);
}
}
app.routing.module.ts
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home';
import { AdminComponent } from './admin';
import { LoginComponent } from './login';
import { AuthGuard } from './_helpers';
import { Role } from './_models';
const routes: Routes = [
{
path: '',
component: HomeComponent,
canActivate: [AuthGuard]
},
{
path: 'admin',
component: AdminComponent,
canActivate: [AuthGuard],
data: { roles: [Role.Admin] }
},
{
path: 'login',
component: LoginComponent
},
// otherwise redirect to home
{ path: '**', redirectTo: '' }
];
export const appRoutingModule = RouterModule.forRoot(routes);
For more information and complete example read this article: Angular 8 - Role Based Authorization Tutorial with Example