Skip to content

4. Implementasi JWT Token

Implementasi JWT Token saat Call ke API

Alt text Alt text

Interface Profile

auth/interface/index.ts
import { BaseResponseSuccess } from "@/lib/axiosClient";

interface User {
  id?: number;
  nama: string;
  email: string;
  password: string;
  refresh_token: string;
  access_token: string;
  avatar: string;
  role: string;
}

...

export interface ProfileResponse extends BaseResponseSuccess {
  data: User;
}

Membuat Service Profile

auth/lib/index.ts
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useToast } from "@/hook";
import {
  LoginPayload,
  LoginResponse,
  ProfileResponse,
  RegisterPayload,
  RegisterResponse,
} from "../interface";
import { axiosClient } from "@/lib/axiosClient";
import { signIn } from "next-auth/react";
import { useRouter } from "next/navigation";

const useAuthModule = () => {
  const { toastError, toastSuccess, toastWarning } = useToast();
  const router = useRouter();

...

  const getProfile = async (): Promise<ProfileResponse> => {
    return axiosClient.get("/auth/profile").then((res) => res.data);
  };

  const useProfile = () => {
    const { data, isLoading, isFetching } = useQuery(
      ["/auth/profile"],
      () => getProfile(),
      {
        select: (response) => response,
        staleTime: 1000 * 60 * 60,
        refetchInterval: 1000 * 60 * 60,
        refetchOnWindowFocus: false,
      }
    );

    return { data, isFetching, isLoading };
  };

  return { useRegister, useLogin, useProfile };
};

export default useAuthModule;

Menggunaakan service profile

admin/page.tsx
"use client";
import React from "react";
import { useSession, signOut } from "next-auth/react";
import Button from "@/components/Button";
import useAuthModule from "../auth/lib";

const Page = () => {
  const {useProfile} = useAuthModule()
  const {data:profile, isFetching} = useProfile()
  const { data: session, status } = useSession();
  console.log('profile', profile)
  return (
    <div>
      Admin
      {JSON.stringify(session)}

      {status}
      <Button
        title="Logout"
        colorSchema="red"
        onClick={() => {
          signOut();
        }}
      />
    </div>
  );
};

export default Page;

Jalankan pada Browser

Alt text

Membuat hook useAuthAxios

hook/useAuthAxios.ts
import { axiosClient } from "@/lib/axiosClient";
import { useSession, signOut } from "next-auth/react";
import { useEffect } from "react";
import { useToast } from ".";

const useAxiosAuth = () => {
  const { data: session } = useSession();
  const { toastWarning } = useToast();

  useEffect(() => {
    const requestIntercept = axiosClient.interceptors.request.use(
      (config: any) => {
        config.headers[
          "Authorization"
        ] = `Bearer ${session?.user?.accessToken}`;

        return config;
      },
      (error: any) => Promise.reject(error)
    );

    const responseIntercept = axiosClient.interceptors.response.use(
      async (response: any) => response,
      async (error: any) => {
        toastWarning(error.response.message);
        signOut();
        window.location.replace("/auth/login");
      }
    );

    return () => {
      axiosClient.interceptors.request.eject(requestIntercept);
      axiosClient.interceptors.response.eject(responseIntercept);
    };
  }, [session, toastWarning]);

  return axiosClient;
};

export default useAxiosAuth;

Implementasi useAuthAxios pada service

auth/lib/index.ts
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useToast } from "@/hook";
import {
  LoginPayload,
  LoginResponse,
  ProfileResponse,
  RegisterPayload,
  RegisterResponse,
} from "../interface";
import { axiosClient } from "@/lib/axiosClient";
import { signIn } from "next-auth/react";
import { useRouter } from "next/navigation";
import useAxiosAuth from "@/hook/useAxiosAuth";
import { useSession } from "next-auth/react";

const useAuthModule = () => {
  const { toastError, toastSuccess, toastWarning } = useToast();
  const axiosAuthClient = useAxiosAuth()
  const {data:session} = useSession()

  const router = useRouter();

...

  const getProfile = async (): Promise<ProfileResponse> => {
    return axiosAuthClient.get("/auth/profile").then((res) => res.data);
  };

  const useProfile = () => {
    const { data, isLoading, isFetching } = useQuery(
      ["/auth/profile"],
      () => getProfile(),
      {
        select: (response) => response,
        staleTime: 1000 * 60 * 60,
        refetchInterval: 1000 * 60 * 60,
        refetchOnWindowFocus: false,
        enabled : session?.user?.id !== undefined
      }
    );

    return { data, isFetching, isLoading };
  };

  return { useRegister, useLogin, useProfile };
};

export default useAuthModule;

Jalankan pada Browser

Alt text Alt text