【问题标题】:Firebase getRedirectResult is being called after logout注销后调用 Firebase getRedirectResult
【发布时间】:2016-12-29 14:48:23
【问题描述】:

我对在 Firebase 中看到的一些行为感到有些困惑。我从未使用过旧版本,但我相信 getRedirectResult 是新的,因为他们与 Google 联手。

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

问题是这样发展的:

  1. 我们在第二页。用户登录。调用 getRedirectResult 并找到用户。耶。
  2. 用户注销。我们又回到了着陆页。
  3. 我们单击一个按钮,将我们带到第二页。调用 getRedirectResult 并找到以前的用户。什么?!不!

我找不到任何关于我是否遗漏了某些内容并需要进行某种额外检查,或者在注销后以某种方式强制刷新页面以使其忘记最后一个用户登录的信息,或者是否会考虑这样做一个错误。任何帮助将不胜感激!

在 vue 组件路由器“激活”钩子的第二页上调用 getRedirectResult:

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

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

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

【问题讨论】:

  • 您好,除了硬刷新之外,您找到解决此问题的方法了吗?
  • @user482594 不;找到该修复程序后,我就停止了工作。
  • 我就此联系了 google firebase 支持团队(案例:0-7351000018196),他们说这是预期的行为.. wtf?据他们说,要从最初使用 Facebook 登录的应用程序中注销用户,该应用程序将需要使用 Facebook SDK 来执行此操作。那不是火力基地!
  • 您好,硬页面刷新是否仍然有效?我在这里尝试,但它总是重定向到/login

标签: javascript firebase vue.js firebase-authentication vue-router


【解决方案1】:

这让我发疯了。正如您将在此处看到的 (https://github.com/firebase/firebase-js-sdk/issues/133),不幸的是,这是预期的行为。

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

这个概念是您在登录页面上放置一个 Route Guard。如果经过身份验证的用户不存在,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;
      }));
  }
}

【讨论】:

  • 这个问题是我确实需要返回 getRidrectResults 以便将用户与我的数据库用户交换(或简单地从我的数据库中获取用户配置文件),所以警卫阻止了这种情况,我被困住了:(
【解决方案2】:

使用标志来检测getRedirectResult() 是否已被处理。即

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

    // Do stuff.

    this.authRedirected = true; // Mark redirected
  });

【讨论】:

    猜你喜欢
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多