You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 15集成Firebase v9 Auth无法持久化会话的解决方法

Angular 15 + Firebase v9 Auth 刷新后用户登出问题解决

问题描述

我正在构建一个Angular v15应用,使用Firebase v9 Auth,认证功能正常,但刷新浏览器时用户会被登出。我在Firebase文档中看到,带有Node.js后端的应用会话持久化被设置为“none”。请问能否使用Firebase Web v9模块化方式,在Angular 15应用中将会话持久化状态设置为“local”?

初始登录组件代码(login.component.ts)

// login.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { initializeApp } from 'firebase/app';
import { getAuth, setPersistence, browserSessionPersistence, signInWithEmailAndPassword } from 'firebase/auth';
import { environment } from '../../environments/environment.prod';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.sass']
})
export class LoginComponent {
  email: string = '';
  password: string = '';
  errorMessage: string = ''; // Variable to hold error message
  
  constructor(private router: Router) {
    initializeApp(environment.firebase);
  }

  // Define auth property
  private auth: any;
  
  login() {
    // Enable local persistence
    this.auth = getAuth();

    setPersistence(this.auth, browserSessionPersistence)
    .then(() => {
      console.log('Local persistence enabled');
      // Existing and future Auth states are now persisted in the current
      // session only. Closing the window would clear any existing state even
      // if a user forgets to sign out.
      return signInWithEmailAndPassword(this.auth, this.email, this.password)
      .then(() => {
        // Navigate to the home page
        this.router.navigate(['/member']);
      })
      .catch((error) => {
        // Check for specific error codes to display appropriate error message
        if (error.code === 'auth/user-not-found' || error.code === 'auth/wrong-password') {
          console.log('Invalid Email or Password');
          // Display error message on the screen or set a variable to show/hide error message in the template
          this.errorMessage = 'Invalid Email or Password'; // Set error message
        } else {
          console.log(error.message);
        }
      });
    })
    .catch((error) => {
      // Handle Errors here.
      console.error('Error enabling local persistence:', error);
    });
  }
}

问题解决:修复后的路由守卫代码

感谢相关帮助,问题已解决。核心问题在于页面刷新时,Firebase Auth需要时间从本地存储恢复会话,直接读取auth.currentUser会得到null,导致路由守卫误判用户未登录。修复后的auth.guard.ts代码如下:

// auth.guard.ts
import { Injectable } from "@angular/core";
import { Router } from "@angular/router";
import { getAuth, onAuthStateChanged } from "firebase/auth";
import { Observable } from 'rxjs';

@Injectable({
  providedIn: "root"
})
export class AuthGuard {

  constructor(private router: Router) {}

  canActivate(): Observable<boolean> {
    return new Observable<boolean>((observer) => {
      const auth = getAuth(); // Get the Firebase auth instance
      console.log('auth.currentUser: ', auth.currentUser);
      onAuthStateChanged(auth, (user) => {
        // Perform user authentication check
        if (auth.currentUser && auth.currentUser.emailVerified) {
          // User is authenticated and email is verified, allow activation
          console.log('User is authenticated and email is verified, allow activation');
          observer.next(true);
        } else {
          // User is not authenticated or email is not verified, redirect to login page
          console.log('User is not authenticated or email is not verified, redirect to login page');
          this.router.navigate(["/login"]); // Replace "/login" with the appropriate route
          observer.next(false);
        }
        observer.complete();
      });
    });
  }
}

关键说明

  1. 会话持久化调整:如果需要关闭浏览器后仍保留登录状态,可将原代码中的browserSessionPersistence替换为browserLocalPersistence,并从firebase/auth中导入该常量。
  2. 路由守卫逻辑优化:通过onAuthStateChanged监听用户状态变化,确保在Firebase完成会话恢复后再进行权限判断,避免页面刷新时的误判。

内容的提问来源于stack exchange,提问作者shwashbuckle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 02:07:09