20

我对 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 = '/'});
4

2 回答 2

1

This drove me crazy. As you'll see here (https://github.com/firebase/firebase-js-sdk/issues/133), this is unfortunately intended behavior.

My approach was to avoid using getRedirectResult() entirely and achieve the same functionality by testing for the presence of an authenticated Firebase user (rather than waiting for the redirect callback). In Angular, you use AngularFire's authState observable. With this approach, when you signOut(), there's no issue with that lingering user in your client memory because it wasn't stored in getRedirectResult().

The concept is that you place a Route Guard on the login page. The Route Guard only lets you on to the login page if an authenticated user isn't present. At that point, you log in, and once that succeeds (signInWithRedirect() always takes a few seconds), the firebase user data is loaded into the client, which triggers the Route Guard to block you from the login page and instead redirect you to the location of your choice.

For bonus points, if you want to preserve the returnUrl, store that string in local storage before firing signInWithRedirect(), and then retrieve it in the Route Guard when the redirect happens (and delete it from local storage).

Inspiration from this Firebase blog post: https://firebase.googleblog.com/2018/03/cleanse-your-angular-components.html. Hopefully this can be applied conceptually to what you are doing in Vue.js.

If you're curious, here's what that Route Guard looks like in Angular 2:

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;
      }));
  }
}
于 2018-11-29T06:44:07.653 回答
0

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

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

    // Do stuff.

    this.authRedirected = true; // Mark redirected
  });
于 2017-10-25T01:37:29.143 回答