【问题标题】:How to store user data in local storage using Capacitor’s Storage Plugin?如何使用 Capacitor 的 Storage Plugin 将用户数据存储在本地存储中?
【发布时间】:2020-05-05 19:45:14
【问题描述】:

我正在尝试将 Firebase 身份验证添加到我的 Angular 应用程序中。

这是我AuthService中的signUp()方法:

signUp(email: string, password: string, name: string) {
    const userCredential = from(
      firebase.auth().createUserWithEmailAndPassword(email, password)
        .then(
          (data) => {

            let newUser: firebase.User = data.user;

            newUser.updateProfile({
              displayName: name,
              photoURL: ''
            }).then(() => {
              firebase.firestore().collection('users').add({
                userId: firebase.auth().currentUser.uid,
                userName: firebase.auth().currentUser.displayName,
                created: firebase.firestore.FieldValue.serverTimestamp()
              });
            });
            Plugins.Storage.set({
              key: 'userCredential',
              value: newUser.uid
            });
          }
        )
    );
    return userCredential;
  }

通过这种方法,我可以使用 Capacitor 的 Storage 插件将newUser.uid 存储在本地存储中。

但我希望能够存储与下面存储的信息相同的信息(即localIdemailidTokenexpirationTime

 login(email: string, password: string) {
    return this.http.post<AuthResponseData>(
      `firebaseUrl/v1/accounts:signInWithPassword?key=${
      environment.firebaseAPIKey
      }`,
      { email: email, password: password, returnSecureToken: true }
    ).pipe(tap(this.setUserData.bind(this)));
  }

private setUserData(userData: AuthResponseData) {
    const expirationTime = new Date(
      new Date().getTime() + (+userData.expiresIn * 1000)
    );
    this._user.next(
      new User(
        userData.localId,
        userData.email,
        userData.idToken,
        expirationTime
      )
    );
    this.storeAuthData(userData.localId, userData.idToken, expirationTime.toISOString(), userData.email);
  }

  private storeAuthData(userId: string, token: string, tokenExpirationDate: string, email: string) {
    const data = JSON.stringify({
      userId: userId,
      token: token,
      tokenExpirationDate: tokenExpirationDate,
      email: email
    });
    Plugins.Storage.set({ key: 'authData', value: data });
  }

有人可以告诉我如何在我的signUp() 方法中获取这 4 个值吗?

【问题讨论】:

    标签: angular typescript firebase firebase-authentication angular-canload


    【解决方案1】:

    根据docs.signInWithEmailAndPassword 返回一个Promise&lt;UserCredential&gt;。这意味着您可以在应用程序状态中保留某种结果来确定当前用户是谁。

    使用localStorage的简单示例:

    login(email: string, password: string) {
      return from(firebase.auth().signInWithEmailAndPassword(email, password));
    }
    

    调用login(..., ...)后,可以将成功结果存储在localStorage中:

    localStorage.createItem('auth', userCredential)

    然后,您可以放心地检查localStorage 中的内容:

    canLoad(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        const userCredential = localStorage.getItem('auth');
        // TODO: some validation step
        return !!userCredential; // or the result of your validation
      }
    

    另一种方法是利用您的 onAuthStateChanged 回调:

    firebase.auth().onAuthStateChanged(user => {
          if (user) {
            localStorage.setItem('auth', user);
            console.log('Logged In User:', user);
          } else {
            console.log('Not Logged In');
            this.router.navigateByUrl('login');
          }
    });
    

    然后很明显,当用户注销或发生应使会话无效的事情时,您希望从 localStorage 中删除该项目:

    localStorage.removeItem('auth');

    我建议采用NgRx 之类的方法或一些状态管理来帮助您管理用户状态,但如果您愿意,可以使用本地存储。就安全性而言,我假设您在每个 API 请求中传递某种 API 密钥或 JWT 以验证用户。

    根据您希望守卫的性能,您还可以查看 firebase API 以查看它是否具有可以在本地存储中调用的任何类型的验证检查。

    例如,在UserCredential 中,您有某种身份验证令牌。然后,您可以使用所述身份验证令牌调用 firebase,如果该令牌是否有效,则该令牌应返回真/假。您可以将其作为一种更“直接”的方式来验证用户访问权限。但是,这也会降低防护的性能,因为每次使用防护时它都必须进行 API 调用。本地存储不会出现这个问题。

    【讨论】:

    • 感谢您的回答。我尝试使用电容器Storage 插件在他们登录时保存用户凭据,然后在canLoad 中使用它,但它目前无法正常工作。我已经努力更新了上面的代码。
    • 我不熟悉那个库。如果你尝试一些简单的事情(比如localStorage),它会起作用吗?
    【解决方案2】:

    AuthServiceLogin()

    login(email: string, password: string) {
        const userCredential = from(firebase.auth().signInWithEmailAndPassword(email, password).then(loggedInUser => {
          Plugins.Storage.set({
            key: 'userCredential',
            value: loggedInUser.user.displayName
          });
        }));
        return userCredential;
      }
    

    Auth Guard

    userCredential;
    
    canLoad(
        route: Route,
        segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
        return Plugins.Storage.get({ key: 'userCredential' }).then(userCredential => {
          this.userCredential = userCredential;
          return this.autoLogin();
        });
      }
    
      autoLogin() {
        if (!this.userCredential || this.userCredential.value === null) {
          this.router.navigateByUrl('login');
          return false;
        } else {
          return true;
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2013-08-17
      • 2018-05-06
      • 1970-01-01
      • 2017-09-01
      • 1970-01-01
      • 2020-07-11
      • 2020-09-19
      • 2018-06-19
      • 2019-10-03
      相关资源
      最近更新 更多