【问题标题】:User is logged out when navigating by url通过 url 导航时用户已注销
【发布时间】:2020-08-23 21:25:49
【问题描述】:

在我的 Angular 应用中,我使用 Firebase 实现了身份验证。 今天我添加了一个404-not found页面,偶然发现了一个奇怪的事件。当登录的用户在浏览器的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' }
];

核心/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);

      });
  }

服务/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;
  }

【问题讨论】:

    标签: javascript angular firebase-authentication angularfire2


    【解决方案1】:

    这很正常。您正在检查服务的属性是否以某种方式被重视,但是当您重新加载页面时,您还会重新加载所有 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 服务的属性仍然有价值。

    编辑:代码。

    编辑 2:尝试使用 localStorage。 从警卫读取它,而不是从 sessionStorage 读取。

    【讨论】:

    • 我已尝试实施此解决方案,但它破坏了应用程序,我无法再登录
    • 用更多代码编辑。你也可以告诉我这一行的控制台输出吗? console.log('sessionStorage.getItem('loggedIn')', sessionStorage.getItem('loggedIn'));我想知道您是否重视该存储空间。
    • 我现在可以登录并使用该应用程序,但通过 url 浏览时我已注销。控制台日志的结果是我的电子邮件地址的两倍,在检查应用程序时,我可以看到我的电子邮件仍存储在会话存储中
    • 替换authentication-service.service.ts中的这行代码: sessionStorage.setItem('loggedIn', email);当您阅读警卫时也是如此: sessionStorage.getItem('loggedIn');用替换编辑了我的答案。
    • 使用localStorage时问题依旧。该值保持不变,但用户已注销
    猜你喜欢
    • 2023-03-15
    • 2020-10-31
    • 2013-11-27
    • 2010-12-26
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多