角度2安全性和可观察性

时间:2017-04-25 15:29:40

标签: angular

作为我们安全的一部分,我们需要对用户进行身份验证,然后在我们调用服务获取数据之前获取权限。如何在Angular 2中进行一系列调用?计划是使安全部分成为一个单独的类,以确保用户通过身份验证并缓存权限。

@Injectable()
export class BankInfoService {
  private _bankInfoUrl = 'http://ourwebsite/api/GetAllClabeBankCodes';
  private _authenticateUrl = 'http://ourwebsite/api/AuthenticateUser';
  private _getRightsUrl = 'http://ourwebsite/api/GetRights';

  constructor(private _http: Http) { }

  getBankInfos(): Observable<BankInfo[]> {

    this._http.get(this._authenticateUrl);

    rights = this._http.get(this._getRightsUrl);

    return this._http.post(this._bankInfoUrl)
        .map((response: Response) => <BankInfo[]> response.json().BankCodes)
        .do(data => console.log('All: ' +  JSON.stringify(data)))
        .catch(this.handleError);
  }


  private handleError(error: Response) {
      console.error(error);
      return Observable.throw(error.json().error || 'Server error');
  }
}

2 个答案:

答案 0 :(得分:1)

缓存信息

Http调用是冷可观察的:每次订阅时都会重新创建它们,你需要的是创建一个热的observable,它将继续发出最后一个值。您可以使用将重播最后n个值的connect()来执行此操作,然后使用refcount()开始发送。您也可以使用export class AuthService { rights: Observable < Rights > ; constructor(private http: Http) { this.rights = this.http.get('url') .map(response => new Rights(resp.json())) //transform http response to Rights object .publishReplay(1); //always replay the last value / transform to hot observable this.rights.connect();// start emitting } ,只要订阅者收听流,就会继续发出值:

switchMap()

关于hot and cold observables here的好文章。

链接:

这是最简单的部分,您可以使用export class BankInfoService { constructor(private authService: AuthService) {} getBankInfos() { return this.authService.rights.flatMap(() => this._http.post(this._bankInfoUrl)) .map((response: Response) => < BankInfo[] > response.json().BankCodes) .do(data => console.log('All: ' + JSON.stringify(data))) .catch(this.handleError); } } 运算符:

  

将每个值映射到Observable,然后使用switch展平所有这些内部Observable。

{{1}}

答案 1 :(得分:1)

我会创建一个执行此AAA任务的AuthGuard。 Guard可以使用使用ReplaySubject缓存数据的服务。以下是路由,服务,防护和组件如何协同工作的示例。

import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser';
import {Routes, RouterModule, Route} from '@angular/router';
import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, 
 RouterStateSnapshot} from '@angular/router';

import 'rxjs/add/operator/switchMap';
import {Http} from '@angular/http';
import {ReplaySubject} from 'rxjs/ReplaySubject';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

@Injectable()
export class AaaService {
  private subject = new ReplaySubject();

  constructor() {
    // replace  Observable.of to your http calls
    Observable.of('user')
      .switchMap(x => Observable.of(['delete', 'edit']))
      .catch(x => Observable.of([]))
      .subscribe(this.subject);
  }

  getRights() {
    return this.subject.asObservable();
  }
}

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private router: Router, private aaaService: AaaService) {
  }

  canActivate(route: ActivatedRouteSnapshot, state: 
      RouterStateSnapshot): Observable<boolean> {
    return this.aaaService.getRights()
      .map((rights: Array<string>) => {
        if (rights.length === 0) {
          this.router.navigate('/login');
        }
        return true;
      });
  }
}

@Component({
  selector: 'my-cpm',
  template: `
    <div>
      hi from component. Rights: {{rights | async | json}}
    </div>
  `,
})
export class MyComponent {
  rights;

  constructor(private aaaService: AaaService) {
    this.rights = aaaService.getRights();
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>Hello {{name}}</h2>
      <router-outlet></router-outlet>
      <a routerLink="/mypath">go to auth path</a>
    </div>
  `,
})
export class App {
  name: string;

  constructor() {
    this.name = `Angular! v${VERSION.full}`
  }
}

const routes = [
  {
    path: 'mypath',
    component: MyComponent,
    canActivate: [AuthGuard]
  }
];

@NgModule({
  imports: [BrowserModule, RouterModule.forRoot(routes)],
  providers: [AaaService, AuthGuard],
  declarations: [App, MyComponent],
  bootstrap: [App]
})
export class AppModule {
}