oct-mwa-common-alt
v1.0.0
Published
octubre modern webapp common alt
Downloads
1
Readme
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>