Firebase getRedirectResult在注销后被调用

Firebase getRedirectResult is being called after logout

本文关键字:调用 注销 getRedirectResult Firebase      更新时间:2023-09-26

我对Firebase的一些行为感到有点困惑。我从未使用过旧版本,但我相信getRedirectResult是新的,因为他们与谷歌合作。

我有一个SPA,我正在使用Vue.js与vue-router和Firebase。有一个登陆页面,然后是另一个视图,用户可以登录,也可以不登录。登录通过重定向完成。当加载第二个视图时,我在vue-router的"activate"钩子中检查getRedirectResult,如果有用户,用用户信息做一些其他的事情。

问题如下:

    我们在第二页。用户登录。调用getRedirectResult并查找用户。耶。
  1. 用户注销。我们回到了着陆页。
  2. 我们点击一个按钮,引导我们到第二页。调用getRedirectResult并查找前一个用户。什么? !不!

我找不到任何关于我是否错过了一些东西,需要某种额外的检查,或者在注销后以某种方式强制刷新页面,以便忘记最后一个用户登录,或者如果这将被认为是一个错误。任何帮助将非常感激!

在vue组件router 'activate'钩子的第二页调用getRedirectResult:

firebase.auth().getRedirectResult()
    .then((result) => {
        return result.user;
    }).then((user) => {
        // Do stuff.
    });

Update:通过在注销回调中进行硬页面刷新来解决,如下所示:

firebase.auth().signOut()
    .then(() => {window.location.href = '/'});

我简直要疯了。正如您将在这里看到的(https://github.com/firebase/firebase-js-sdk/issues/133),不幸的是,这是有意为之的行为。

我的方法是完全避免使用getRedirectResult(),并通过测试是否存在经过身份验证的Firebase用户来实现相同的功能(而不是等待重定向回调)。在Angular中,你使用AngularFire的authState observable。使用这种方法,当您执行signOut()时,在客户端内存中不存在滞留用户的问题,因为它没有存储在getRedirectResult()中。

这个概念就是你在登录页面上放置了一个Route Guard。路由保护只允许你进入登录页面,如果一个身份验证的用户不存在。在这一点上,您登录,一旦成功(signInWithRedirect()总是需要几秒钟),firebase用户数据被加载到客户端,这会触发Route Guard阻止您登录页面,而不是将您重定向到您选择的位置。

对于额外的点,如果你想保留returnUrl,在触发signInWithRedirect()之前将该字符串存储在本地存储中,然后在重定向发生时在Route Guard中检索它(并从本地存储中删除它)

灵感来自Firebase博客文章:https://firebase.googleblog.com/2018/03/cleanse-your-angular-components.html。希望这能在概念上应用到你在Vue.js中所做的事情。

如果你很好奇,可以看看Angular 2中的Route Guard:

import { Injectable } from '@angular/core';
import { AuthService } from './auth.service';
import { Router, CanActivate } from '@angular/router';
import { map } from 'rxjs/operators';
@Injectable({
  providedIn: 'root'
})
export class LoginGuardService implements CanActivate {
  constructor(
    private auth: AuthService,
    private router: Router
  ) { }
  canActivate() {
    return this.auth.firebaseUser$.
      pipe(map(user => {
        // The firebaseuser determines if user is logged in
        // If logged in, block the route with a redirect
        if (user) {
          console.log('User detected', user);
          const returnUrl = localStorage.getItem('returnUrl');
          // Route user to returnUrl, if none, go to profile
          if (returnUrl && returnUrl !== '/') {
            this.router.navigate([returnUrl]);
          } else {
            this.router.navigate(['profile']);
          }
          return false;
        }
        return true;
      }));
  }
}

使用一个标志来检测getRedirectResult()是否已被处理。例如

firebase.auth().getRedirectResult()
  .then((result) => {
    return result.user;
  }).then((user) => {
    if (this.authRedirected)
      return; // Skip
    // Do stuff.
    this.authRedirected = true; // Mark redirected
  });