如何将凭据存储到本地存储以允许 Firebase 身份验证登录 [英] How to Store Credentials to Local Storage to Allow Firebase Auth to Sign-in

查看:28
本文介绍了如何将凭据存储到本地存储以允许 Firebase 身份验证登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个 Angular 10 项目中工作,我也在使用 Firebase 托管和云 Firestore(用于 DB).我也在我的项目中使用 AngularFire.

I'm working in an Angular 10 project, I am also using firebase hosting and cloud firestore (for DB). I am using AngularFire in my project as well.

我的项目已经能够从我的 firestore 集合中获取文档并显示它们(也可以编辑、删除和创建它们).我还设置了身份验证,在这里我使用 AngularFireAuth 登录和注销.我也有路线守卫,只允许用户在登录后访问信息.

My project is already able to get documents from my firestore collection, and display them (also can edit, delete, and create them). I also set up authentication, where I use AngularFireAuth to sign in and sign out. I also have route guards to only allow users access to info after signing in.

我发现 Firestore 也有规则,您应该对其进行设置以保护您的收藏.目前,我基本上没有规则(测试模式),但我想添加一个基本的只有用户可以访问任何东西"规则,但我遇到了一个问题.

I've discovered that Firestore also has rules, and that you should set them up to secure your collection. Currently, I basically have no rules (test mode), but I want to add a basic "only users can access anything" rule, but am running into an issue.

我认为这是问题所在,目前,登录我的应用程序后会将用户存储在本地存储中.我认为我需要以不同的方式存储它,所以我从以前给定的凭据重新登录,而不仅仅是检查是否有本地存储.当我的守卫检查本地存储以确保登录时,我只会收到 ERROR FirebaseError: Missing or enough permissions 错误,如果我先登录,我不会收到错误.

I think this is the issue, currently, after logging in my app will store the user in local storage. I think that I need to store this a different way so I am re-signed in from previously given creds instead of just checking if there local storage. I only get ERROR FirebaseError: Missing or insufficient permissions errors when my guard checks the local storage to ensure sign-in, if I sign-in first, I don't get the error.

那么,我应该如何保存用户数据,这样我就不必在每次刷新时都登录,但我可以验证 firebase 的身份验证?我知道我可以将电子邮件/密码存储到本地存储并检查以重新登录,但这对我来说似乎不安全.

So, how should I save user data so that I don't have to sign-in on every refresh, but that I can verify the auth to firebase? I know I could store the email/password to local storage and check to re sign-in, but that seems insecure to me.

我认为以上是问题所在,但不是 100% 确定.

I think the above is the issue, but not 100% sure.

这是我的firestore规则:

This is my firestore rule:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
  allow read, write: if request.auth != null
    match /{document=**} {
      allow read, write: if request.auth != null //should only allow users?
    }
  }
}

这是我的身份验证服务(我处理登录/注销并检查本地存储是否有用户.

Here is my auth service (where I handle sign-in/sign-out and check if local storage has user.

export class AuthService {
  constructor(private aFAuth: AngularFireAuth, public router: Router) {
    //I honestly don't know if I need this
    this.aFAuth.authState.subscribe((user) => {
      if (user) {
        localStorage.setItem('my-test-app-currentUser', JSON.stringify(user));
      } else {
        localStorage.setItem('my-test-app-currentUser', null);
      }
    });
  }

  async signIn(email: string, password: string) {
    this.aFAuth
      .signInWithEmailAndPassword(email, password).then((result) => {
        localStorage.setItem('my-test-app-currentUser', JSON.stringify(result.user));
        this.router.navigate(['']);
      }).catch((error) => {
        window.alert(error.message);
      });
  }

//this is the func that needs to change, if I have storage, I need to be able to sign-in with it again
  isSignedIn(): boolean {
    if (!localStorage.getItem('my-test-app-currentUser')) {
      return false;
    }
    return true;
  }

  signOut() {
    return this.aFAuth.signOut().then(() => {
      localStorage.removeItem('my-test-app-currentUser');
      window.alert('You have been signed-out');
    });
  }
}

这里是我的守卫:

canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    // return true;
    if (this.auth.isSignedIn()) {
      return true;
    } else {
      this.router.navigate(["sign-in"]);
      return false;
    }
  }

任何帮助将不胜感激.

推荐答案

Firebase 已经将用户凭据存储在本地存储中,并在您重新加载页面时自动恢复它们.

Firebase already stores the user credentials in local storage, and automatically restores them when you reload the page.

恢复它们确实需要对服务器进行检查,所以它是异步发生的.出于这个原因,任何依赖于用户身份验证状态的代码都应该在 this.aFAuth.authState.subscribe 处理程序中,以便它在身份验证状态发生变化时运行.

Restoring them does require a check against the server though, so it happens asynchronously. For that reason, any code that depends on the user's authentication state should be inside the this.aFAuth.authState.subscribe handler, so that it runs whenever the authentication state changes.

因此,不要在 signInWithEmailAndPassword 调用完成时处理导航,这种情况仅在您主动登录用户时发生,导航应位于 auth 侦听器中,该侦听器在主动登录和正在恢复中.

So instead of handling the navigation when the signInWithEmailAndPassword call completes, which happens only when you actively sign the user in, the navigation should be in the auth listener, which runs both on active sign in and on a restore.

比如:

export class AuthService {
  constructor(private aFAuth: AngularFireAuth, public router: Router) {
    //I honestly don't know if I need this
    this.aFAuth.authState.subscribe((user) => {
      if (user) {
        localStorage.setItem('my-test-app-currentUser', JSON.stringify(user));
        this.router.navigate(['']);
      } else {
        localStorage.setItem('my-test-app-currentUser', null);
      }
    });
  }

  async signIn(email: string, password: string) {
    this.aFAuth
      .signInWithEmailAndPassword(email, password).then((result) => {
        window.alert(error.message);
      });
  }
  ...

在您的 canActivate 中,您可能想要使用 AngularFireAuthGuard.这确保未经身份验证的用户不被允许导航到受保护的路线.我认为这可能会取代您对本地存储的全部需求.

In your canActivate you'll probably want to use the AngularFireAuthGuard. which ensures that unauthenticated users are not permitted to navigate to protected routes. I think this might replace your entire need for local storage.

另请参阅关于 入门的 AngularFire 文档Firebase 身份验证使用 AngularFire 防护路由用户.

Also see the AngularFire documentation on Getting started with Firebase Authentication and Route users with AngularFire guards.

这篇关于如何将凭据存储到本地存储以允许 Firebase 身份验证登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆