Как хранить пользовательские данные в локальном хранилище с помощью плагина Capacitor's Storage? - PullRequest
0 голосов
/ 05 мая 2020

Я пытаюсь добавить Firebase Authentication в свое приложение Angular.

Вот метод signUp() в моем AuthService:

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;
  }

С помощью этого метода я Я могу хранить newUser.uid в локальном хранилище с помощью плагина Capacitor Storage.

Но я хочу иметь возможность хранить ту же информацию, что и то, что хранится ниже (а именно localId, email , idToken & expirationTime:

 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 });
  }

Кто-нибудь, пожалуйста, скажите мне, как я могу получить эти 4 значения в моем методе signUp()?

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Согласно docs , .signInWithEmailAndPassword возвращает Promise<UserCredential>. Это означает, что есть какой-то результат, который вы можете сохранить в своем состоянии приложения, чтобы определить, кто является текущим пользователем.

Простой пример с использованием 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 или JWT с каждым запросом API для проверки пользователя.

В зависимости от того, насколько производительным вы хотите, чтобы охранник был, вы можете также загляните в API firebase, чтобы узнать, есть ли у него какая-либо проверка, которую вы можете вызвать на месте в localstorage.

Примером может быть то, что в UserCredential у вас есть какой-то токен авторизации. Затем вы можете вызвать firebase с указанным токеном аутентификации, который должен вернуть истину / ложь, если это действительный токен или нет. Вы можете встроить это в свою защиту как более «прямой» способ проверки доступа пользователя. Но это также снизит производительность защиты, поскольку она должна выполнять вызов API каждый раз, когда используется защита. Локальное хранилище не представляет такой проблемы.

0 голосов
/ 06 мая 2020

AuthService Login():

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;
    }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...