Пользователь выходит из системы при навигации по URL - PullRequest
1 голос
/ 08 мая 2020

В моем приложении Angular я реализовал аутентификацию с помощью Firebase. Сегодня я добавил страницу с ошибкой 404 и наткнулся на странный инцидент: когда вошедший в систему пользователь вводит путь в URL-адресе браузера, пользователь выходит из системы. Сначала я подумал, что это произошло, потому что пути не существует, но это также происходит с существующими путями. При навигации с помощью кнопок (и использовании Router.navigateByUrl()) этого не происходит.

app-routing.module.ts

const routes: Routes = [
  {path: '', redirectTo: 'enter-lokaal', pathMatch: 'full'},
  {path: 'login', component: LoginComponent},
  {path: 'enter-lokaal', component: EnterLokaalComponent, canActivate: [AuthGuard]},
  {path: 'lokaal/:id', component: LokaalComponent, canActivate: [AuthGuard]},
  {path: 'lokaalOverzicht/:id', component: LokaalOverzichtComponent, canActivate: [AuthGuard]},
  { path: '404', component: NotfoundComponent, canActivate: [AuthGuard] },
  { path: '**', redirectTo: '/login' }
];

Core / auth.guard.ts

export class AuthGuard implements CanActivate {

  constructor(private authService: AuthenticationServiceService, private router: Router) {

  }

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.authService.user$.pipe(
      take(1),
      map((user: User) => {
        if (user) {
          return true;
        }
        this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
        return false;
      })
    );
  }
 }

services / authentication-service.service.ts

export class AuthenticationServiceService {
  // user$: Observable<User>;
  userEmail: string;
  user: Observable<firebase.User>;

  user$: Observable<User>;

  errorMessage: string;

  constructor(
    private afAuth: AngularFireAuth,
    private  router: Router,
    private usersService: UsersService

  ) {
    this.user$ = this.afAuth.authState;
  }

  private logInErrorSubject = new Subject<string>();

  public getLoginErrors(): Subject<string> {
    return this.logInErrorSubject;
  }

  login(email: string, password: string) {
    this.afAuth.auth.signInWithEmailAndPassword(email, password)
      .then(value => {
        sessionStorage.setItem('loggedIn', email);
        console.log('Nice, it worked!', value.user);

        this.usersService.setSelectedUserByEmail(email);
        console.log(this.usersService.getSelectedUser());

        this.router.navigateByUrl('/enter-lokaal');
      })
      .catch(err => {
        this.logInErrorSubject.next(err.message);
        console.log('Something went wrong: ', err.message);

      });
  }

services / users.service.ts

export class UsersService {
  usersCollection: AngularFirestoreCollection<User>;
  users: Observable<User[]>;
  selectedUser: User;

  constructor(public afs: AngularFirestore) {
    this.usersCollection = this.afs.collection('gebruikers');
    this.users = this.usersCollection.valueChanges();
  }

  getUsers() {
    return this.users;
  }

  /*getUserByUID(uid: string) {
    return this.getUsers().subscribe(users => users.find(user => user.uid === uid));
  }*/
  setSelectedUserByEmail(email: string) {
    this.users.subscribe(users => {
      this.selectedUser = users.find(user => user.email === email);
      console.log(this.selectedUser);
    });
  }

  getSelectedUser() {
    console.log(this.selectedUser);
    return this.selectedUser;
  }

1 Ответ

0 голосов
/ 08 мая 2020

Это нормально. Вы проверяете, оценивается ли свойство службы определенным образом, но когда вы перезагружаете страницу, вы также перезагружаете все javascript, и эта информация теряется, на этом этапе: return this.authService.user$

проверка, которую вы должны выполнить на хранилище:

// auth.guard.ts
...
constructor(private _router: Router) {}

public canActivate(
      next: ActivatedRouteSnapshot,
      state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {

    console.log('localStorage.getItem('loggedIn')', localStorage.getItem('loggedIn'));
    if (typeof localStorage.getItem('loggedIn') !== 'undefined') {
      return true;
    }
    // console.log(this._router.url);
    if (this._router.url !== '/login') {
      this._router.navigate(['login']);
    }
    return false;
    // return this.router.parseUrl('/login');
}
...

Замените эту строку кода в authentication-service.service.ts :

sessionStorage.setItem('loggedIn', email);

На это:

localStorage.setItem('loggedIn', email);

Когда вы перемещаетесь внутри приложения, вы на самом деле не меняете страницы (это механизм маршрутизации Angular), и свойство службы authentication-service.service.ts остается в силе.

EDIT: Код.

РЕДАКТИРОВАТЬ 2: Попробуйте использовать localStorage. Прочтите его от охраны, вместо sessionStorage.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...