Angular 6: получить токен из localStorage после обновления - PullRequest
0 голосов
/ 13 ноября 2018

РЕДАКТИРОВАТЬ: я обновляю код с ответом, который мне дал PierreDuc. Он решение работает для меня. Я редактирую код, чтобы все могли видеть рабочий код

Я использую canActivate и canActivateChild, чтобы узнать, есть ли у кого-то токен для моей сети, и я хочу заблокировать любого, у кого его еще нет. Я использую localStorage для пользовательских данных и токена.

Когда я пытаюсь войти в систему с идентификатором пользователя: 1, охранник переходит на страницу, которая не найдена, но после обновления страницы я получаю доступ к странице. Когда я использовал отладчик, я увидел, что перед обновлением localStorage был пуст, но имел значения после обновления.

Почему это происходит? как я могу это исправить? Это соответствующий код:

приложение-routing.module.ts

const appRoutes: Routes = [
  { path: 'login/:id', canActivate: [AuthGuard], children: [] },
  { path: '', canActivateChild: [AuthGuard], children: [
    { path: '', redirectTo: '/courses', pathMatch: 'full' },
    { path: 'courses', component: CourseListComponent,  pathMatch: 'full'},
    { path: 'courses/:courseId', component: CourseDetailComponent, pathMatch: 'full' },
    { path: 'courses/:courseId/unit/:unitId', component: CoursePlayComponent,
      children: [
        { path: '', component: CourseListComponent },
        { path: 'lesson/:lessonId', component: CourseLessonComponent, data:{ type: 'lesson'} },
        { path: 'quiz/:quizId', component: CourseQuizComponent, data: {type: 'quiz'} }
      ]}
    ]},
  { path: '**', component: PageNotFoundComponent, pathMatch: 'full' }];

auth.guard.ts

export class AuthGuard implements CanActivate , CanActivateChild {

    constructor(private authUserService: AuthUserService, private router: Router) {   }

    canActivate(route: ActivatedRouteSnapshot, state:
    RouterStateSnapshot): boolean |
    Observable<boolean> | Promise<boolean> {
      // save the id from route snapshot
      const id = +route.params.id;

      // if you try to logging with id
      if (id) {
        this.router.navigate(["/courses"]);
        return this.authUserService.login(id);
      }

      // if you already logged and just navigate between pages
      else if (this.authUserService.isLoggedIn())
         return true;

      else {
        this.router.navigate(["/page_not_found"]);
        return false;
      }
     }

      canActivateChild(route: ActivatedRouteSnapshot,state: RouterStateSnapshot): boolean |
      Observable<boolean> | Promise<boolean> {
         return this.canActivate(route, state);
       }

}

Auth-user.service.ts

import { Injectable, OnDestroy } from '@angular/core';
import { Observable , BehaviorSubject } from 'rxjs';
import { LocalStorage } from '@ngx-pwa/local-storage';
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
import { catchError, groupBy } from 'rxjs/operators';

import { UserService } from './user.service';
import { IUser } from './user';

@Injectable()
export class AuthUserService implements OnDestroy {

  private user: IUser;
  private errorMessage: string;

  constructor(private userService: UserService) { }

  // store the session and call http get
  login(id: number) {
    return this.userService.getUser(id).pipe(
      map((user) => {
        this.user = user;
        localStorage.setItem('user', JSON.stringify(this.user));
        localStorage.setItem('token', 'JWT');
        return true;
      }),
      catchError((error) => {
        this.errorMessage = <any>error;
        return of(false);
      })
    );
  }

  isLoggedIn() {
   return !!localStorage.getItem('token');
  }

  ngOnDestroy() {
    localStorage.removeItem('user');
    localStorage.removeItem('token');
  }
}

1 Ответ

0 голосов
/ 13 ноября 2018

userService.getUser - асинхронный, он не будет завершен и установит ваш localStorage после того, как вы уже проверили его.

Измените ваш authService на:

login(id: number) {
  return this.userService.getUser(id).pipe(
    map((user) => {
      this.user = user;
      localStorage.setItem('user', JSON.stringify(this.user));
      localStorage.setItem('token', 'JWT');
      return true;
    }),
    catchError((error) => {
      this.errorMessage = <any>error;
      return of(false);
    })
  );
}

И обновитеВаша охрана на это:

if (id) {
  this.router.navigate(["/courses"]);
  return this.authUserService.login(id);
}
...