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);
    })
  }