Reputation: 312
So I have a simple angular 2/laravel app wit jwt authentification support. I have a service that verifies everytime a route is called if the jwt token is valid or not using the angular2-jwt tokenNotExpired() function, but this function always return false for a reason, so the user would be always redirected to login page.
So it goes like that the user logs in, a token will be generated from the backend and saved on local storage, than a service will check if the token is valid before initiating any route using the CanActivate lifecycle hook.
Here is what i did so far:
Login Component:
...
this.http.post(SERVER_URL + 'auth', body, {
headers: headers
}
).subscribe(
data => {
localStorage.setItem('auth_token', data.json().token);
this.authHttp.get(SERVER_URL + 'auth/user', headers)
.subscribe(
data => {
this.store.dispatch({ type: SET_CURRENT_USER_PROFILE, payload: data.json().user });
localStorage.setItem('user', data.json().user);
this.router.navigate(['/home']);
},
err => console.log('Fehlermeldung: ' + err)
);
},
...
app.module :
...
{ provide: AuthConfig, useValue: new AuthConfig({
headerName: 'Authorization',
headerPrefix: 'Bearer ',
tokenName: 'auth_token',
tokenGetter: (() => localStorage.getItem('auth_token')),
globalHeaders: [{ 'Content-Type': 'application/json' }],
noJwtError: true,
noTokenScheme: true
})},
AuthHttp
...
auth.service : // Check JWT token service
import { tokenNotExpired } from 'angular2-jwt';
import { Injectable } from '@angular/core';
@Injectable()
export class AuthService {
loggedIn() {
return tokenNotExpired();
}
}
auth.guard.service :
// Check if the Token of the user is still valid
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { CanActivate } from '@angular/router';
import { AuthService } from './auth.service';
import { AppState } from '../shared/interfaces';
import { SET_CURRENT_USER_PROFILE } from '../shared/state.actions';
import { Store } from '@ngrx/store'
@Injectable()
export class AuthGuardService implements CanActivate {
constructor(private auth: AuthService, private router: Router, private store: Store<AppState>) {}
canActivate() {
if(this.auth.loggedIn()) {
return true;
} else {
console.log ('Token expired or not valid')
localStorage.setItem('auth_token', '');
localStorage.setItem('user', '');
this.store.dispatch({ type: SET_CURRENT_USER_PROFILE, payload: null });
this.router.navigate(['/']);
return false;
}
}
}
app.routing :
const routes: Routes = [
{ path: 'home', component: HomeComponent},
{ path: 'about', component: AboutComponent, canActivate: [AuthGuardService]},
{ path: 'profile/:id', component: ProfileComponent, canActivate: [AuthGuardService]},
{ path: '', component: LoginComponent}
];
EDIT: From the backend side everything is normally ok since the token is generated and stored in the localstorage after the user logs in.
Upvotes: 1
Views: 2638
Reputation: 51
Pass the token as a parameter.
Change
loggedIn() {
return tokenNotExpired();
}
to
loggedIn() {
return tokenNotExpired('id_token');
}
Upvotes: 0
Reputation: 6778
`localStorage.setI`tem('id-token',token);
the same token name used for saving token to local storage/session storage can be pass as an argument to
return tokenNotExpired('id-token');
Upvotes: 0
Reputation: 555
Its because of the property name, it assumes it is "token". So when you provide the property name as first parameter, it will work properly.
For example:
tokenNotExpired('auth_token')
Some more information on the matter can be found here: https://github.com/auth0/angular2-jwt/issues/334
Upvotes: 2
Reputation: 312
SOLUTION: So this is how i fixed it for everyone who may have the same problem, i used JWTHelper function isTokenExpired() instead of tokenNotExpired and I inversed the logic in the service and it worked not really sure why though
auth.service looks like that now :
@Injectable()
export class AuthService {
private jwtHelper: JwtHelper = new JwtHelper();
private token = localStorage.getItem('auth_token');
isExpired() {
return this.jwtHelper.isTokenExpired(this.token);
}
}
and auth.guard.service canActivate():
canActivate() {
if (this.auth.isExpired()) {
console.log (this.auth.isExpired());
localStorage.setItem('auth_token', '');
localStorage.setItem('user', '');
this.store.dispatch({ type: SET_CURRENT_USER_PROFILE, payload: null });
this.router.navigate(['/']);
return false;
} else {
return true;
}
}
Upvotes: 1