No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Manejo de headers

17/23
Recursos

Luego de que el usuario se halla registrado, puedes utilizar el token para realizar peticiones al backend que requieran de autenticaci贸n. Para esto, es necesario inyectar dicho token en las solicitudes HTTP.

Autenticaci贸n del Usuario

Para esto, puedes obtener el token desde Local Storage (o si prefieres guardarlo en Cookies) e inyectarlo directamente en los Headers de la petici贸n.

// services/auth.service.ts
getProfileUser(): Observable<User> {
  const token = localStorage.getItem('platzi_token');
  return this.http.get<User>(`https://example.com/api/profile`, {
    headers: {
      Authorization: `Bearer ${token}`
    }
  });
}

El protocolo de este tipo de token suele emplear la palabra Bearer seguido de un espacio por delante del propio token.

Puede ser bastante engorroso tener que inyectar el token, m茅todo por m茅todo en todos los endpoints que necesitas consumir. Puedes simplificar esto con una 煤nica funci贸n que construya los headers.

// services/auth.service.ts
import { HttpHeaders } from '@angular/common/http';

getProfileUser(): Observable<User> {
  return this.http.post<User>(`https://example.com/api/profile`, this.getHttpHeaders());
}

getHttpHeaders() {
  const token = localStorage.getItem('platzi_token');
  return {
    headers: new HttpHeaders({
      Authorization: `Bearer ${token}`
    })
  };
}

La clase HttpHeaders construye los header en la funci贸n getHttpHeaders() y llamas a dicha funci贸n para que inyecte los headers en cada solicitud.

Es una forma m谩s elegante y limpia de inyectar los headers necesarios en tus solicitudes.


Contribuci贸n creada por: Kevin Fiorentino.

Aportes 8

Preguntas 1

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Reg铆strate o inicia sesi贸n para participar.

Para poder hacer lo del new HttpHeaders() no me funciono lo visto en clase鈥

Buscando en google me funciono lo siguiente:

let headers = new HttpHeaders();
    headers = headers.set('Authorization', `Bearer ${token}`);

Esta fue mi solucion 馃槷

login() {
    this.authService.login('[email protected]', '123456')
      .pipe(
        switchMap((token) => {
          this.token = token.access_token;
          return this.authService.profile(token.access_token);
        })
      )
      .subscribe(user => {
        this.profile = user;
      });
  }

Mi solucion fue bastante mas floja, deje todo donde estaba y utilice un input para pasar el componente padre app al componente hijo nav el email.

Adapt茅 un poco la l贸gica para que, en caso de que el usuario nuevo no exista, habilite un bot贸n para la creaci贸n del usuario visitante

nav.component.ts

import { Component, OnInit } from '@angular/core';
import { switchMap } from 'rxjs/operators';

import { Product } from 'src/app/interfaces/product.model';
import { User } from 'src/app/interfaces/user.model';
import { AuthService } from 'src/app/services/auth.service';
import { StoreService } from 'src/app/services/store.service';
import { UsersService } from 'src/app/services/users.service';
import Swal from 'sweetalert2';

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

  myCart: Product[] = [];
  activeMenu = false;

  profile: User = {
    id: '',
    email: '',
    password: '',
    name: ''
  }

  visitante = {
    name: 'Visitante',
    email: '[email protected]',
    password: '1212'
  }

  token = '';
  createdUser = true;

  constructor(
    private storeService: StoreService,
    private auth: AuthService,
    private user: UsersService
  ) {
    this.myCart = this.storeService.getShoppingCart();
  }

  ngOnInit(): void {
  }

  toggleMenu(){
    this.activeMenu = !this.activeMenu;
  }

  createUser(){
    this.createdUser = !this.createdUser;
    this.user.create(this.visitante)
    .subscribe(rta => {
      Swal.fire({
        title: 'Usuario creado',
        text: `Bienvenido ${this.visitante.name}`,
        icon: 'success',
        confirmButtonText: 'Super!'
      })
    })
  }

  login() {
    this.auth.login('[email protected]', '1212')
    .pipe(
      switchMap((token) => {
        this.token = token.access_token;
        return this.auth.profile(token.access_token)
      })
    )
    .subscribe(user => {
      this.profile = user;
    }, err => {
      this.createdUser = !this.createdUser;
      Swal.fire({
        title: err.error.statusCode,
        text: err.error.message,
        icon: 'error',
        confirmButtonText: 'Close'
      })
    });
  }
}

nav.component.html

<button *ngIf="!createdUser" (click)="createUser()">Crear Usuario</button>

me qued贸 con la sensaci贸n de que estas clases son demaciado especificas, no siento que pueda generalizar esta informaci贸n a varios contextos, siento que explica todo como si de un tutorial para trabajar con esta api en especifico se tratase, lo que a煤n despues de haber entendido lo que explica me queda la sensaci贸n de no haber aprendido.

en app.component.ts est谩 as铆, y para un manejo reactivo cre茅 un observable donde se guarde el profile.

 this.authService
      .login('[email protected]', 'qwerty')
      .pipe(
        switchMap(({ access_token }) => this.authService.profile(access_token)),
        switchMap((profile) => this.authService.setCurrentProfile(profile))
      )
      .subscribe();

El observable dentro de auth.service.ts


export class AuthService {
  private apiUrl = `${environment.API_URL}/api/auth`;
  private profileStore = new BehaviorSubject<IUser>({} as IUser);
  profileStore$ = this.profileStore.asObservable();
  constructor(private http: HttpClient) {}

  login(email: string, password: string) {
    return this.http.post<IAuth>(`${this.apiUrl}/login`, { email, password });
  }

  setCurrentProfile(user: IUser) {
    this.profileStore.next(user);
    return this.profileStore$;
  }
  profile(token: string) {
    const headers = new HttpHeaders();
    headers.set('Authorization', `Bearer ${token}`);
    return this.http.get<IUser>(`${this.apiUrl}/profile`, {
      headers: { Authorization: `Bearer ${token}` },
    });
  }
}

https://angular.io/guide/http

Les dejo un poquito de teoria oficial de angular para reforzar este tema 鉂わ笍

Hola,

Esta fue la solucion que hice con switchMap, pero la respuesta del subscrbe me sale undefined.

login(){
    this.AuthService.login('[email protected]','1234567')
    .pipe(
      switchMap((token)=>
      {
        return this.AuthService.profile(token.access_token).pipe(
          map(item =>{
            this.profile = item,
            this.token = token.access_token
          })
        )
      }
      )
    )
    .subscribe(response=>{      
      console.log(response);
    })
  }