Angular 5 AngularFire Firebase Логин Flicker - PullRequest
0 голосов
/ 28 мая 2018

Я использую AngularFire2 для создания системы входа в систему с Firebase и Angular 5. Когда я нажимаю кнопку входа и выхода, все работает хорошо.Единственная проблема заключается в том, что я получаю мерцание, если я обновляю страницу, как показано ниже.Очевидно, это происходит потому, что для загрузки javascript требуется время.Какой лучший способ справиться с этой проблемой?Обычно я создаю системы входа в систему на PHP или другом языке бэкэнда, поэтому у меня никогда не возникает этой проблемы, потому что я просто проверяю переменные SESSION для входа в систему, и страницы не завершают загрузку, пока это не произойдет.Здесь страница загружается сразу, а затем Javascript проверяет, вошли ли вы в систему.

Я знаю, что могу использовать загрузочный счетчик, но мне не нравятся сайты, использующие этот трюк.Другой возможностью является использование файлов cookie Javascript или JWT.Я просто хочу выяснить, что является лучшей практикой.

Также нет системы входа в систему, использующей Firebase и Angular, небезопасной, потому что пользователи могут просто изменять переменные Javascript?Например, пользователи могут просто установить afAuth.user.Личная панель пользователя проверяет, установлена ​​ли эта переменная, и позволяет пользователю просматривать эту страницу, если она есть.Так что никто не мог просто войти в приватную панель управления, установив переменную afAuth.user.Я понимаю, что могу защитить данные Firebase, используя правила, и могу гарантировать, что пользователи вошли в систему перед доступом к базе данных.Но кажется, что HTML-код не может быть скрыт от пользователей, если вы используете Firebase для аутентификации с помощью внешнего интерфейса Javascript.

enter image description here

Вот app.component.html

<div *ngIf="afAuth.user | async as user; else showLogin">
  <h1>Hello {{ user.displayName }}!</h1>
  <button (click)="logout()">Logout</button>
</div>
<ng-template #showLogin>
  <p>Please login.</p>
  <button (click)="login()">Login</button>
</ng-template>

<router-outlet></router-outlet>

Мой app.component.ts файл

import { Component } from '@angular/core';
import { AngularFirestore } from 'angularfire2/firestore';
import { AngularFireAuth } from 'angularfire2/auth';
import { auth } from 'firebase/app';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'app';

  constructor(public afAuth: AngularFireAuth) {
  }
  login() {
    var email = "test@test.com";
    var password = "testpass";
    return this.afAuth.auth.signInWithEmailAndPassword(email, password)
      .then((user) => {
        console.log(user);
      })
      .catch((error) => {
        console.log(error)
      });
  }
  logout() {
    this.afAuth.auth.signOut();
  }
}

app.module.ts файл

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { LoginComponent } from './login/login.component';

import { AlertModule } from 'ngx-bootstrap';

import { AngularFireModule } from 'angularfire2';
import { AngularFirestoreModule } from 'angularfire2/firestore';
import { AngularFireStorageModule } from 'angularfire2/storage';
import { AngularFireAuthModule } from 'angularfire2/auth';
import { environment } from '../environments/environment';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    AlertModule.forRoot(),
    AngularFireModule.initializeApp(environment.firebase),
    AngularFirestoreModule,
    AngularFireAuthModule,
    AngularFireStorageModule
  ],
  providers: [],
  bootstrap: [ AppComponent ]
})
export class AppModule { }

1 Ответ

0 голосов
/ 10 июля 2018

Прежде всего, аутентификация AngularFire ничем не отличается от того, к чему вы привыкли.Единственная большая разница в том, что вы получаете уведомление при изменении состояния аутентификации (это происходит с наблюдаемым / обещанием).вы все равно можете получить его так, как привыкли: this.af.auth.currentUser.Однако значение может быть уже устаревшим (пользователь где-то вышел или сеанс истек)

Когда вы получаете уведомление о состоянии авторизации, у вас всегда будет какой-то эффект вспышки.Либо это вся ваша страница, либо просто это сообщение.

Я поместил весь свой сайт (кроме страницы входа в систему) за охранником .Охранник проверяется перед загрузкой маршрута и выглядит примерно так:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
  return this.af.authState.pipe(
    map(auth => {
      if (isNullOrUndefined(auth)) {
        this.router.navigate(['/login']); //Redirect if not authenticated
        return false;
      } else {
        return true;
      }
    })
  );
}

В компоненте входа в систему вы можете подписаться на authState и перенаправить при успешном входе.

ngOnInit() {
  this.subsciption = this.af.authState.pipe(defaultIfEmpty()).subscribe(auth => {
    this.logginIn = false;
    if (!isNullOrUndefined(auth)) {
      this.router.navigate(['/overview']); //Redirect succesfull login
    }
  }, console.log, () => {
    this.logginIn = false;
  });
}

logginIn используется для отображения счетчика.

Об этой проблеме безопасности.Да, любой может увидеть ваш HTML, но это не должно быть проблемой.Это ваши данные, которые вы хотите (и должны) защитить.Этот HTML - просто модная кожаная куртка.

...