Currently, after logging in I'm able to get the JWT to the frontend. My app currently has a logging page as the landing page and as soon as the user logins the route checks for authentication to redirect to the guarded home path.
My first intuition was to send a boolean from the backend (Django) and use that to create a guard. But I keep seeing that seems to be better practice to handle this in the front end.
What I did was create an auth.service.ts and an auth.guard.ts. In the service, I try to retrieve the token from the browser and then verify that it hasn't expired. Then I call that method on the guard and return a boolean. Problem is that every time I look for the token in the local storage, I get back null.
Is there any better way to get achieve this?
auth.guard.ts
import { Injectable } from '@angular/core';
import {
ActivatedRouteSnapshot,
CanActivate,
Router,
RouterStateSnapshot,
UrlTree,
} from '@angular/router';
import { Observable, of } from 'rxjs';
import { catchError, map } from 'rxjs/operators';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root',
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
):
| Observable<boolean | UrlTree>
| Promise<boolean | UrlTree>
| boolean
| UrlTree {
console.log(this.authService.isAuthenticated());
if(!this.authService.isAuthenticated()){
this.router.navigate(['/login']);
return false;
}
return true;
}
}
auth.service.ts
import { Injectable } from '@angular/core';
import { JwtHelperService } from '@auth0/angular-jwt';
@Injectable({
providedIn: 'root'
})
export class AuthService {
public jwtHelper: JwtHelperService = new JwtHelperService();
constructor() { }
isAuthenticated(){
const jwt = localStorage.getItem('token');
return !this.jwtHelper.isTokenExpired(jwt!);
}
}
app-routing.module.ts
...
import { AuthGuard } from './user/services/auth.guard'
const routes: Routes = [
{
path: '',
component: LandingComponent,
children: [
{ path: '', component: HomeComponent, canActivate: [AuthGuard],},
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard],},
{
path: 'cohort-charts',
component: CohortChartsComponent,
children: [
{ path: 'selection', component: CohortSelectionComponent },
{ path: 'edit', component: CohortEditComponent },
{ path: '', redirectTo: 'selection', pathMatch: 'full' },
],
},
],
},
{
path: 'login',
component: LoginComponent,
},
{ path: '**', redirectTo: '' },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}