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

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

问题描述

我正在Angular 10项目中工作,我也在使用Firebase托管和Cloud 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:缺少权限不足或错误错误,如果我先登录,则不会收到该错误.

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 Guard路由用户.

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

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