1.0.0 • Published 1 year ago

oct-mwa-common-alt v1.0.0

Weekly downloads
-
License
ISC
Repository
-
Last release
1 year ago

OCT Modern Web App Common

Libreria de servicios npm con typescript

https://www.npmjs.com/package/oct-mwa-common

Usage

//...

import { JwtModule, JWT_OPTIONS } from '@auth0/angular-jwt';

import {
  BaseErrorTrackerService,
  BaseJwtHelperService,
  BaseNotificationService,
  BaseStorageService,
  BaseAuthBackendCallerService,
  BaseLoaderService,
  TokenStoreService,
  OCT_MWA_COMMON_SERVICES,
} from 'oct-mwa-common';

//...

// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
export function jwtOptionsFactory(tokenStoreService: TokenStoreService) {
    return {
      tokenGetter: () => tokenStoreService.accessToken,
      //No se agrega accessToken
      disallowedRoutes: [
        // /api/auth
        /.*\/auth.*/,
      ],
      headerName: 'Authorization',
      authScheme: 'Bearer ',
      //Si el token esta vencido, se envia igual
      skipWhenExpired: false
    };
}

@NgModule({
  declarations: [AppComponent],
  entryComponents: [
    //...
  ],
  imports: [
    //...    
    JwtModule.forRoot({
      jwtOptionsProvider: {
        provide: JWT_OPTIONS,
        useFactory: jwtOptionsFactory,
        deps: [TokenStoreService]
      }
    }),
  ],
  providers: [
    //...    
    ...OCT_MWA_COMMON_SERVICES,
    {
      provide: BaseAuthBackendCallerService,
      useClass: MyAuthBackendCallerService,//Implementación local
      multi: false
    },
    {
      provide: BaseJwtHelperService,
      useClass: MyJwtHelperService,//Implementación local
      multi: false
    },
    {
      provide: BaseStorageService,
      useClass: MyStorageService,//Implementación local
      multi: false,
    },
    {
      provide: BaseNotificationService,
      useClass: MyNotificationService,//Implementación local
      multi: false,
    },
    {
      provide: BaseErrorTrackerService,
      useClass: MyErrorTrackerService,//Implementación local
      multi: false,
    },
    {
      provide: BaseLoaderService,
      useClass: MyLoaderService,//Implementación local
      multi: false,
    }
  ],
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  bootstrap: [AppComponent],
})
export class AppModule {}

Al hacer peticiones

this.http.post(`/api/mi-endpoint`, data, { headers })

La librería @auth0/angular-jwt se encargará de agregar el header de autenticación

Cómo obtener usuario?

Cada opción será mejor según el caso

Opcion 1: Subscription (Reactivo)

En este caso, el código reaccionará ante cada cambio (si se cierra sesión o si el usuario cambia)

import { Component, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { AuthService } from 'oct-mwa-common';
import { MyJWTParserService } from './services';

@Component({
  selector: 'app-help',
  templateUrl: './help.page.html',
  styleUrls: ['./help.page.scss'],
})
export class HelpPage implements OnInit {

  text: string = 'No hay usuario';
  getAccessTokenSubscription: Subscription;

  constructor(private authService: AuthService,
              private myJWTParserService: MyJWTParserService) 
              { }

  ngOnInit() {
    this.getAccessTokenSubscription = this.authService.getAccessToken().subscribe(
      accessToken => {
        if(!!accessToken){
          const username = this.myJWTParserService.decodeAccessToken(accessToken).nameIdentifier;
          this.text = `El usuario es ${username}`;
        }
        else {
          this.text = 'No hay usuario';
        }
      }
    );
  }

  ngOnDestroy() {
    this.getAccessTokenSubscription.unsubscribe();
  }

}
<ion-header>
  <ion-toolbar>
    <ion-title>help</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

<div>
  {{ text }}
</div>  

</ion-content>

Opcion 2: Async pipe (Reactivo)

En este caso, el código reaccionará ante cada cambio (si se cierra sesión o si el usuario cambia)

import { Component, OnInit } from '@angular/core';
import { Observable, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
import { AuthService } from 'oct-mwa-common';
import { MyJWTParserService } from './services';

@Component({
  selector: 'app-help',
  templateUrl: './help.page.html',
  styleUrls: ['./help.page.scss'],
})
export class HelpPage implements OnInit {

  parsedAccessToken$ : Observable<string | null>;

  constructor(private authService: AuthService,
              private myJWTParserService: MyJWTParserService) 
              { }

  ngOnInit() {
    this.parsedAccessToken$ = this.authService.getAccessToken()
      .pipe(
        map(rawAccessToken => {
            return this.myJWTParserService.decodeAccessToken(accessToken);
        })
      );
  }

}
<ion-header>
  <ion-toolbar>
    <ion-title>help</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

<div *ngIf="parsedAccessToken$ | async as pat">
  El usuario es {{ pat.nameIdentifier }}
</div>  

</ion-content>

Opción 3: Propiedad authUser (No reactivo)

El código no reaccionará ante los cambios. Esta manera es para obtener el usuario una única vez

import { Component, OnInit } from '@angular/core';
import { AuthService } from 'oct-mwa-common';
import { MyJWTParserService } from './services';

@Component({
  selector: 'app-help',
  templateUrl: './help.page.html',
  styleUrls: ['./help.page.scss'],
})
export class HelpPage implements OnInit {

  parsedAccessToken: any;

  constructor(private authService: AuthService,
              private myJWTParserService: MyJWTParserService) { }

  async ngOnInit() {
    this.parsedAccessToken = this.myJWTParserService.decodeAccessToken(this.authService.accessToken);
  }

}
<ion-header>
  <ion-toolbar>
    <ion-title>help</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

<div>
  El usuario es {{ parsedAccessToken.nameIdentifier }}
</div>  

</ion-content>

Opcion 4: Take + Promise (No reactivo)

Esta opción no se recomienda, pero está a modo de ejemplo. En todo caso se recomienda usar la opción anterior

El código no reaccionará ante los cambios. Esta manera es para obtener el usuario una única vez

import { Component, OnInit } from '@angular/core';
import { map, take } from 'rxjs/operators';
import { AuthService } from 'oct-mwa-common';
import { MyJWTParserService } from './services';

@Component({
  selector: 'app-help',
  templateUrl: './help.page.html',
  styleUrls: ['./help.page.scss'],
})
export class HelpPage implements OnInit {

  text: string = 'No hay usuario';
  parsedAccessToken: any;

  constructor(private authService: AuthService,
              private myJWTParserService: MyJWTParserService) { }

  async ngOnInit() {
    this.parsedAccessToken = await this.authService.getAccessToken()
      .pipe(
        map(rawAccessToken => {
            return this.myJWTParserService.decodeAccessToken(accessToken);
        }),
        take(1)
      ).toPromise();
  }

}
<ion-header>
  <ion-toolbar>
    <ion-title>help</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>

<div>
  El usuario es {{ parsedAccessToken.nameIdentifier }}
</div>  

</ion-content>
1.0.0

1 year ago