Название приложения: Вход в приложение
В основном я захожу в приложение через компонент входа в систему (http://localhost:4200/login).. Он перенаправляет его в компонент администратора, если есть пользователь, которому я передаю объект. Это работает нормально. Но как только я обновляюсь страница администратора (http://localhost:4200/admin). Я перенаправлен обратно на страницу входа (http://localhost:4200/login) страница. Даже если я успешно вошел в систему.
Вот необходимый код.
auth.service.ts
import { Injectable } from '@angular/core';
import { UserModel } from './user';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/map';
const USERS = [
{username: 'admin', password: '12345', role: 'ADMIN'},
{username: 'user', password: '67890', role: 'USER'}
]
let userObservable = Observable.of(USERS);
@Injectable()
export class AuthService {
constructor() { }
private loginUrl = '/login';
private redirectUrl = '/admin';
private loggedInUser: UserModel;
private isLoggedIn: boolean = false; //This is the value I am making true/false
getAllUsers(): Observable<UserModel[]> {
return userObservable;
}
isAuthenticated(username: string, password: string): Observable<boolean> {
return this.getAllUsers()
.map(users => {
let user = users.find(user => (user.username === username) && (user.password === password));
if(user) {
this.isLoggedIn = true;
this.loggedInUser = user;
} else {
this.isLoggedIn = false;
}
return this.isLoggedIn; // boolean value to use found user
})
}
isUserLoggedIn() {
return this.isLoggedIn;
}
getRedirectUrl() {
return this.redirectUrl;
}
setRedirectUrl(url) {
this.redirectUrl = url;
}
getLoginUrl() {
return this.loginUrl;
}
getLoggedInUser(): UserModel {
return this.loggedInUser;
}
logoutUser(): void {
this.isLoggedIn = false;
}
}
Auth-guard.service.ts
import { Injectable } from '@angular/core';
import { AuthService } from './auth.service';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
@Injectable()
export class AuthGuardService implements CanActivate {
constructor(private authService: AuthService, private router: Router) { }
canActivate(activatedRoute: ActivatedRouteSnapshot, routerState: RouterStateSnapshot) {
let url: string = routerState.url;
let user = this.authService.getLoggedInUser();
if(this.authService.isUserLoggedIn()) {
return true;
}
this.authService.setRedirectUrl(url);
this.router.navigate([this.authService.getLoginUrl()])
return false;
}
}
login.component.html
<form [formGroup]="loginForm" (ngSubmit)="onSubmit()">
<p>
<label for="">Username </label><input type="text" formControlName="username">
</p>
<p>
<label for="">Password </label><input type="text" formControlName="password">
</p>
<button>Submit</button>
</form>
login.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { AuthService } from '../assets/auth.service';
@Component({
selector: 'la-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
constructor(private authService: AuthService, private router: Router) { }
ngOnInit() {
}
loginForm = new FormGroup({
username: new FormControl(),
password: new FormControl()
})
onSubmit(){
let uname = this.loginForm.get('username').value;
let pass = this.loginForm.get('password').value;
this.authService.isAuthenticated(uname, pass).subscribe(
(authenticated) => {
if(authenticated) {
let url = this.authService.getRedirectUrl();
this.router.navigate([url]);
}
}
)
}
}
app.routing.module
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { AdminComponent } from './admin/admin.component';
import { UserComponent } from './user/user.component';
import { AuthGuardService } from './assets/auth-guard.service';
const routes: Routes = [
{'path': '', redirectTo: '/login', pathMatch: 'full'},
{'path': 'login', component: LoginComponent},
{'path': 'admin', component: AdminComponent, canActivate: [ AuthGuardService ]},
{'path': 'user', component: UserComponent}
]
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
exports: [RouterModule]
})
export class RoutingModule {}
Причина перенаправления на страницу входа после нажатия кнопки обновления в браузере : Это потому, что когда я нажимаю обновить приложение. Он перезагружает все и в auth.service (isLoggedIn: boolean = false) это то, что приложение получает при перезагрузке приложения. Так что выйдите из приложения.
Моя Startegy: я использую @ ngx-pwa / local-storage для установки и получения значения, подобного этому
// Установка значения при успешном входе в систему
this.localStorage.setitem('token','isLoggedIn).subscribe(()=>{})
// получение значения при обновлении внутри метода canActivate. Который должен сравнивать его со строковым значением, если значение соответствует возвращаемому true и компонент администратора загружается
this.localStorage.getitem('token').subscribe((res)=>{ console.log(res) // how to use this value outside of this scope so to compare it with string metioned below})
Это обновленный код для login.component.ts
onSubmit(){
let uname = this.loginForm.get('username').value;
let pass = this.loginForm.get('password').value;
this.authService.isAuthenticated(uname, pass).subscribe(
(authenticated) => {
if(authenticated) {
let url = this.authService.getRedirectUrl();
let user = this.authService.getLoggedInUser();
this.localStorage.setItem('token', 'isLoggedIn').subscribe(()=>{});
this.router.navigate([url]);
console.log(user)
}
}
)
Это обновленный код для auth.gaurd service
checkIsLoggedIn: string;
canActivate(activatedRoute: ActivatedRouteSnapshot, routerState: RouterStateSnapshot) {
let url: string = routerState.url;
let user = this.authService.getLoggedInUser();
this.localStorage.getitem('token').subscribe(
(res) => { this.checkIsLoggedIn = res }
)
if(this.checkIsLoggedIn == 'IsLoggedIn' //here it is getting undefined the value never goes out ) {
return true;
}
this.authService.setRedirectUrl(url);
this.router.navigate([this.authService.getLoginUrl()])
return false;
}
Как я могу управлять состоянием приложения в этом приложении, чтобы обновление не нарушало представление. или, если возможно, как использовать @ngrx localstorage для установки / получения значений и сравнения их в методе canActivate, или есть какой-то другой способ.