I've been pulling my hairs out trying to figure out what is the reason that my user value is null after login.
this is my login page. it calls an api and gets the result as seen below:
and this is my authentication service:
export class AuthenticationService {
private userSubject: BehaviorSubject<User>;
public user: Observable<User>;
constructor(
private router: Router,
private http: HttpClient
) {
this.userSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('user')));
this.user = this.userSubject.asObservable();
}
public get userValue(): User {
return this.userSubject.value;
}
GetUsername(): string {
if (localStorage.getItem('currentUser') != null)
return JSON.parse(localStorage.getItem('currentUser')).UserName;
return null;
}
login(username: string, password: string) {
return this.http.post<any>(`${Statics.ApiUrl}users/authenticate`, { Username: username, Password: password }, { responseType: "json" })
.pipe(map(user => {
debugger;
localStorage.setItem('user', JSON.stringify(user));
this.userSubject.next(user);
return user;
}));
}
logout() {
//remove user from local storage to log user out
localStorage.removeItem('user');
this.userSubject.next(null);
this.router.navigate(['/login']);
}
signUp(RegisterModel: RegisterModel): Observable<User> {
return this.http.post<User>(`${Statics.ApiUrl}users/signup`, RegisterModel, { responseType: "json" });
}
verifyUserPhone(username: string, password: string, verificationCode: string): Observable<User> {
return this.http.put<User>(Statics.ApiUrl 'users/verifyUserPhone', { username, password, verificationCode }, { responseType: "json" });
}
}
And here is my authguard:
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private authenticationService: AuthenticationService
) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
debugger;
const user = this.authenticationService.userValue;
var token_expiration=new Date(user?.TokenExpirartion);
var now=new Date();
if (user && token_expiration>now) {
// check if route is restricted by role
if (route.data.roles && route.data.roles.indexOf(user.role) === -1) {
// role not authorised so redirect to home page
this.router.navigate(['/']);
return false;
}
// authorized so return true
return true;
}
// not logged in so redirect to login page with the return url
this.authenticationService.logout();
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } });
return false;
}
}
i login and i get the user data and i store it the local storage but my authguard never lets route to be activated because authentication service always return user NULL.If I only refresh the page then it works. and as for logout it does not logout user untill I refresh the page.
see it below:
this is my login button ts code :
this.AuthenticationService.login(this.username, this.password)
.pipe(first())
.subscribe({
next: () => {
// get return url from query parameters or default to home page
const returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
this.router.navigateByUrl(returnUrl);
},
error: error => {
this.error = error;
this.submited = false;
}
});
When authguard checks for userSubject after loging-in it returns null. no matter how many times I login it will return null unless I refresh the page. only then userSubject gets evaluated. I don't know what to do. I can't login to my site. i have to login and then refresh the page to make authguard work.
after refreshing page i have the value:
CodePudding user response:
It seems like the auth service takes some time to fetch data, and by then the route is already rejected as it got null.
You can try adding some wait before approving/rejecting a route
CodePudding user response:
Are your services provided in root? If not, you may be getting multiple instances.
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
...



