刷新后如何让用户保持登录到 Firebase 应用程序?

Posted

技术标签:

【中文标题】刷新后如何让用户保持登录到 Firebase 应用程序?【英文标题】:How do I keep a user logged into a firebase app after refresh? 【发布时间】:2015-11-22 01:46:54 【问题描述】:

我有一个内置于 firebase 和 angular 的应用程序,我希望能够在刷新页面后让用户保持登录状态。现在我有一个登录屏幕,其中包含两个绑定到控制器的基本输入字段

    this.email = "";
    this.pass = "";
    this.emessage = "";

    this.loginUser = function() 
        ref.authWithPassword(
            email: this.email,
            password: this.pass
        , function(error, authData) 
            if (error) 
                console.log("Login Failed!", error);
                this.emessage = error.message;
                $scope.$apply();
             else 
                dataStorage.uid = authData.uid;
                $location.path('/projects');
                $scope.$apply(); 
            
        .bind(this));
    

这一切都很好,而且很有效,但是当用户刷新页面时,他们会被注销。有没有办法在控制器加载时查看用户是否已经登录并自动重定向?谢谢!

【问题讨论】:

在 Session 或 LocalStora 中保存访问令牌? 如何做到这一点。如果这个问题过于宽泛,我深表歉意。 【参考方案1】:

您现在拥有的代码处理用户登录的情况。要处理用户已经登录的情况,您可以使用onAuthStateChanged 方法:

firebase.auth().onAuthStateChanged(function(user) 
  if (user) 
    // User is signed in.
   else 
    // User is not signed in.
  
);

通常您只想在此函数的 else 中显示登录按钮。

Documentation: firebase.auth.Auth


旧答案(已弃用/存档)

您现在拥有的代码处理用户登录的情况。要处理用户已经登录的情况,您可以监控身份验证状态。来自Firebase documentation on monitoring auth state:

// Create a callback which logs the current auth state
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.onAuth(function(authData) 
  if (authData) 
    console.log("User " + authData.uid + " is logged in with " + authData.provider);
   else 
    console.log("User is logged out");
  
);

通常您只想在此函数的else 中显示登录按钮。

【讨论】:

不客气。直到最近,我一直忽略这个问题,并在试图隐藏我的登录按钮时遇到各种问题,所以很高兴有机会告诉我这是多么微不足道一旦你知道如何。。跨度> 看起来onAuth 已被弃用。见firebase.google.com/docs/reference/js/… @FrankvanPuffelen 我正在使用onAuthStateChanged,它的效果不是很好,因为当我刷新时,我的应用程序会在应用程序启动之前显示“注销状态”(如登录按钮等)然后显示正确的东西。我应该在本地存储东西还是 cookie 或其他东西以使这个过程看起来更顺畅? 存储一个本地(最好是同步的)值是我知道的唯一让这个更快的方法。请记住,您本地的“他们已登录”值可能有误,并确保在这种情况下将它们发送回登录屏幕。【参考方案2】:

如评论中所述,已接受的答案不再有效。当前检查用户是否登录的方法是

firebase.auth().onAuthStateChanged(function(user) 
  if (user) 
    // User is signed in.
  
);

(来自https://firebase.google.com/docs/reference/js/firebase.auth.Auth#onAuthStateChanged)

【讨论】:

【参考方案3】:

我面临的挑战是我的网络应用程序的公共页面具有受保护的功能。使用以下代码,用户总是先通过 Firebase SDK 加载(如果已登录)。但如果页面需要身份验证,也会被重定向到登录页面。这适用于页面重新加载。

Router.beforeEach((to, from, next) => 

  // If route required authentication
  if (to.matched.some(record => record.meta.requiresAuth)) 

    // Load user
    firebase.auth().onAuthStateChanged(user => 

      // If user obj does not exist --> redirect to login page
      if (!user) 
        next( name: 'login' );
       else 
        store.commit("user/SET_USER", user);
        user.getIdToken().then(token => 
          store.commit("user/SET_TOKEN", token)
        );

        next();
      
    );
   else 

    // Path does not required auth - Still we check the user
    firebase.auth().onAuthStateChanged(user => 

      // If user exist (is logged in) --> store in state.
      if (user)   
        store.commit("user/SET_USER", user);
        user.getIdToken().then(token => 
          store.commit("user/SET_TOKEN", token)
        );
        next();

       else 
        next();
      
    );
  
)

【讨论】:

嘿,如果您能提供有关代码本身的更多信息,例如您正在为哪个文件编写代码等,那将非常有帮助。【参考方案4】:

对于任何 ReactJS 用户,这是我根据此线程中提供的答案创建的一个简单 Hook,如果当前用户未登录,它将重定向用户到登录路由。

import  useEffect  from 'react';
import * as firebase from 'firebase';
import  useHistory  from 'react-router-dom';

export default function useProtectedRoute() 
  const history = useHistory();

  useEffect(() => 
    firebase.auth().onAuthStateChanged(function(user) 
      if (!user) 
        console.error(
          'Access to protected route denied, redirecting to login...'
        );
        history.push('/auth/login');
      
    );
  , [history]);

你只需要导入这个钩子并在任何你不想渲染的组件中运行,除非用户登录。

示例:

import React from 'react';
import useProtectedRoute from 'hooks/useProtectedRoute';

export default function UserDetailsComponent() 
  useProtectedRoute();
  return <div>This is only visible when user is logged in</div>;

【讨论】:

【参考方案5】:

如果您使用的是 Angular 4,您可以使用 AngularFire2 - 官方 Firebase 集成。

我有一个包装 AngularFire2 的 AuthService。我只是在 Service 的构造函数中检索 AuthSession 并在需要时使用它。示例:

@Injectable()
export class AuthenticationService 

    private authState: any;

    constructor(public afAuth: AngularFireAuth) 
        this.afAuth.authState.subscribe((auth) => 
          this.authState = auth
        );
    

    get user(): any 
        return this.authenticated ? this.authState : null;
    

完整认证服务码here 带有 Firebase 示例的完整 Angular 4 here

【讨论】:

【参考方案6】:

其他选项sessionStorage

看这里:

Angular Firebase auth, how to check if user is logged in to hide login link from navigation?

【讨论】:

以上是关于刷新后如何让用户保持登录到 Firebase 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Firebase 刷新令牌保持用户身份验证?

即使关闭应用程序,如何保持用户登录?我正在使用 swift 3 和 Firebase

Firebase:如何让 Android 用户保持登录状态?

Angular 2 - Firebase 在页面刷新时保持登录状态

页面刷新后如何保持用户登录

如何修复 Firebase Auth 仅在刷新后工作?