so i want to implement auth guard to redirect user to login page if he is not logged in yet.
For example , when am in login page , when i type "/dashboard" in my url , i want the user to be redirected to login in case he is not authenticated , but it's not working , it just stays at the login page no matter what , and even if i'm authenticated it doesn't go to dashboard page anymore.
I'm really stuck and it's frustrating because whatever i did it just doesn't work, there must be something wrong that i haven't noticed.
I really need help to solve this , thanks in advance !
This is my token storage service :
logout_user() : void{
localStorage.clear();
this.isAuthenticate = false;
this.router.navigate(['login']);
}
public saveToken(token : string) : void {
localStorage.removeItem(TOKEN_KEY);
localStorage.setItem(TOKEN_KEY,token);
}
public getToken() : string | null {
return localStorage.getItem(TOKEN_KEY);
}
public saveUser(user:any) : void {
localStorage.removeItem(USER_KEY);
localStorage.setItem(USER_KEY,JSON.stringify(user));
}
public getUser() : any {
const user = localStorage.getItem(USER_KEY);
if(user){
this.isAuthenticate = true;
return JSON.parse(user);
}
return this.isAuthenticate;
}
This is my auth guard page
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
const isLoggedin = this.tokenService.getToken();
if(!isLoggedin){
this.router.navigate(['/login']);
console.log(isLoggedin);
alert("You are not logged in yet");
return false;
}
return true;
}
This is my login component
ngOnInit(): void {
if(this.tokenStorage.getToken()){
this.isLoggedIn = true;
this.router.navigate(['dashboard']);
this.roles = this.tokenStorage.getUser().roles;
console.log(this.tokenStorage.getToken());
console.log(this.tokenStorage.getUser());
}
}
onSubmit() : void {
const {username , password} = this.form;
this.authService.login_user(username,password).subscribe(
data_user => {
this.tokenStorage.saveToken(data_user.accessToken);
this.tokenStorage.saveUser(data_user);
this.isLoggedIn = true;
this.roles = this.tokenStorage.getUser().roles;
this.router.navigate(['dashboard']);
},
error_login => {
this.errorMessage = error_login.error.message;
this.isLoginFailed = true;
console.log(this.errorMessage);
return this.isLoggedIn;
}
);
}
These are my routes
export const AdminLayoutRoutes: Routes = [
{ path: 'dashboard', component: DashboardComponent, canActivate : [AuthGuard]},
{ path: 'user-profile', component: UserProfileComponent},
{ path: 'table-list', component: TableListComponent },
{ path: 'typography', component: TypographyComponent },
{ path: 'icons', component: IconsComponent },
{ path: 'maps', component: MapsComponent },
{ path: 'notifications', component: NotificationsComponent },
{ path: 'upgrade', component: UpgradeComponent },
{ path: 'jobDetail', component: JobDetailComponent },
{ path: 'candidateProfile', component: CandidateProfileComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'my-profile', component: MyprofileComponent },
{ path: 'userDetail/:id', component: UserDetailsComponent }
];
These are my app module routes
const routes: Routes =[
{
path: '',
component : LoginComponent
},
{
path: '',
component: AdminLayoutComponent,
children: [{
path: '',
loadChildren: () => import('./layouts/admin-layout/admin-layout.module').then(m => m.AdminLayoutModule)
}]
},
{
path : 'login',
component: LoginComponent
}
];
This is my auth Service :
import { HttpClient,HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';
import { User } from 'app/models/user.model';
import { Router } from '@angular/router';
import { TokenRegistrationService } from './token-registration.service';
const AUTH_API = 'http://localhost:8080/api/auth/';
const httpOptions = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};
export interface SignUpData {
username: string;
first_name : string;
last_name : string;
profession : string;
email: string;
password: string;
roles: string[];
}
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
private userSubject: BehaviorSubject<User>;
public user: Observable<any>;
isAuthenticate = false;
constructor(private http : HttpClient,private router : Router,private tokenService : TokenRegistrationService) {
}
//Login service for user authentication , sends data inside observable through the AUTH_API/signin and if it matches existing user , authenticates
login_user(username: string, password: string): Observable<any> {
return this.http.post(AUTH_API + 'signin', {
username,
password,
}, httpOptions);
}
//Signup service for user account creation , sends data inside observable throught the AUTH_API/signup and if data is valid , creates account
register_user(user : SignUpData) : Observable<any>{
return this.http.post(AUTH_API + 'signup',user,httpOptions);
}
}
successful and unseccessful handling :
<div
class="alert alert-danger"
role="alert"
*ngIf="f.submitted && isLoginFailed"
>
Login failed: {{ errorMessage }}
</div>
<button [disabled]="loading" class="btn btn-primary">
<span *ngIf="loading" class="spinner-border spinner-border-sm mr-1"></span>
Login
</button>
<div *ngIf="errorMessage" class="alert alert-danger mt-3 mb-0">{{errorMessage}}</div>
</form>
</div>
</div>
<div class="alert alert-success" *ngIf="isLoggedIn">
Logged in as {{ roles }}.
</div>
This shows alert-success if i loging and error message if not
Ths is my data after login successful :
{id: 46, username: 'azizos', first_name: 'azizoo', last_name: 'azz', profession: 'sezer', …}
accessToken: "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJheml6b3MiLCJpYXQiOjE2NDk4ODc5NzksImV4cCI6MTY0OTk3NDM3OX0.2GivL_V7ZnRzF4otPX-KZ20qe9pS-W1BOJmFmeQoNnhN7o_82PUvKmDnJEeumRu0dRWmSE46uGfxmqvo7feTxQ"
email: "azizos.gmail@com"
first_name: "azizoo"
id: 46
last_name: "azz"
profession: "sezer"
roles: ['ROLE_HR_MANAGER']
tokenType: "Bearer"
username: "azizos"
Ah yes the classic
pathMatch: 'full'
oversight.Without that, all routes will always match the empty string, because the default match strategy is 'prefix' and an empty path is a prefix of all other URLs.
From the docs: https://angular.io/api/router/Route