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(); }); }); } }
关键说明
- 会话持久化调整:如果需要关闭浏览器后仍保留登录状态,可将原代码中的
browserSessionPersistence替换为browserLocalPersistence,并从firebase/auth中导入该常量。 - 路由守卫逻辑优化:通过
onAuthStateChanged监听用户状态变化,确保在Firebase完成会话恢复后再进行权限判断,避免页面刷新时的误判。
内容的提问来源于stack exchange,提问作者shwashbuckle
相关产品推荐
相关产品推荐

