Menggunakan Authentication Pada Project Buku Resep – 9

Jika Anda melakukan fetch recipe, akan terjadi error. Karena pada Firebase, kita sudah set untuk read dan write data memerlukan authentication. Sementara code kita saat ini belum menambahkan authentication pada saat melakukan request.

Data user dapat diakses pada auth.service.ts, namun saat ini user didefinisikan sebagai subject, dimana untuk mendapatkan valuenya perlu dilakukan proses subscribe.

Untuk keperluan itu, kita akan modifikasi dengan menambahkan property token, dimana akan diset melalui method handleAuth.

Buka file auth.service.ts, ubah menjadi seperti berikut:

import {Injectable} from '@angular/core';
import {HttpClient, HttpErrorResponse} from '@angular/common/http';
import { catchError, tap } from 'rxjs/operators';
import { Subject, throwError } from 'rxjs';
import { User } from './user.model';

export interface AuthResponse {
    idToken: string;
    email: string;
    refreshToken: string;
    expiresIn: string;
    localId: string;
    registered?: boolean; 
}

@Injectable({providedIn: 'root'})
export class AuthService {
    user = new Subject<User>();
    //tambahkan property baru
    token = "";

    constructor(private http: HttpClient){}

    signUp(email: string, pswrd: string){
        return this.http
        .post<AuthResponse>('https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIzaSyAHq81IV8SqS_n6KL9wEmuB_qs3_8J4szU',
            {
                email: email, 
                password: pswrd, 
                returnSecureToken: true
            }
        )
        .pipe(catchError(this.errHandling), tap(respData=>{
            this.handleAuth(respData.email, respData.localId, respData.idToken, +respData.expiresIn);
        }));
    }

    login(email: string, pswrd: string){
        return this.http
        .post<AuthResponse>('https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyAHq81IV8SqS_n6KL9wEmuB_qs3_8J4szU',
            {
                email: email, 
                password: pswrd, 
                returnSecureToken: true                
            }
        ).pipe(catchError(this.errHandling), tap(respData=>{
            this.handleAuth(respData.email, respData.localId, respData.idToken, +respData.expiresIn);
        }));   
    }

    private handleAuth(email: string, userId: string, token: string, expiresIn: number){
        const expDate = new Date(new Date().getTime()+ (expiresIn*1000));
        const user = new User(email, userId, token, expDate);
        this.user.next(user);
        //set nilai token
        this.token = token;
    }

    private errHandling(errResp: HttpErrorResponse){
        let errMsg = 'Unknown Error...';

        if (!errResp.error || !errResp.error.error){
            return throwError(errMsg);
        }
        switch(errResp.error.error.message){
            case 'EMAIL_EXISTS':      
                errMsg = 'Email sudah terdaftar';
                break;
            case 'EMAIL_NOT_FOUND':
                errMsg = 'User belum terdaftar';
                break;
            case 'INVALID_PASSWORD':
                errMsg = 'User atau Password salah';
                break;                
        }
        return throwError(errMsg);
    }
}

Kemudian buka file data-storage.service.ts, ubah bagian method untuk fetch

import { Injectable } from "@angular/core";
import { HttpClient, HttpParams } from "@angular/common/http";
import { map, tap } from "rxjs/operators";

import { Recipe } from "../recipes/recipe.model";
import { RecipeService } from "../recipes/recipe.service";
import { AuthService } from "../auth/auth.service";

@Injectable({providedIn: 'root'})
export class DataStorageService{
    //inject authService
    constructor(private http: HttpClient, private recipeSrv : RecipeService, private authSrv: AuthService){}

    storeRecipes(){
        const recipes = this.recipeSrv.getRecipes();
        this.http
        .put('https://ng-buku-resep-c435d-default-rtdb.asia-southeast1.firebasedatabase.app/recipes.json',
            recipes)
        .subscribe(response =>{
            console.log(response);
        });
    }

    //tambahkan auth sebagai params (aturan dari firebase auth digunakan dalam param )
    fetchRecipes(){
        return this.http
        .get<Recipe[]>('https://ng-buku-resep-c435d-default-rtdb.asia-southeast1.firebasedatabase.app/recipes.json',
        {
            params : new HttpParams().set('auth', this.authSrv.token)
        }
        )
        .pipe(
            map(recipes=>{
                return recipes.map(recipe=>{
                    return {...recipe, ingredients: recipe.ingredients ? recipe.ingredients : []};
                });
            }), 
            tap(recipes =>{
                this.recipeSrv.setRecipes(recipes);
            })
        );
    }
}

Jika Anda test, sesuai ekspektasi, sekarang data sudah berhasil dibaca dari server.

Silakan Anda tambahkan juga params pada method save data, Atau Anda bisa menggunakan interceptor untuk handling setiap request dan response.

Sharing is caring:

Leave a Comment