From 50496ebd73e9fbd5f1a5f0614db846f08f12ee1e Mon Sep 17 00:00:00 2001 From: hanif salafi Date: Fri, 10 Jan 2025 02:34:39 +0700 Subject: [PATCH] feat: update CSRF Security on Login and API --- .../rewrite/create/[id]/page.tsx | 2 +- components/landing-page/hero.tsx | 18 ++++++ components/partials/auth/login-form.tsx | 10 ++-- service/auth.ts | 60 ++++++++++++++++++- service/http-config/axios-base-instance.ts | 1 + .../http-config/axios-interceptor-instance.ts | 7 ++- 6 files changed, 87 insertions(+), 11 deletions(-) diff --git a/app/[locale]/(public)/content-management/rewrite/create/[id]/page.tsx b/app/[locale]/(public)/content-management/rewrite/create/[id]/page.tsx index 3f582c9a..f82b734f 100644 --- a/app/[locale]/(public)/content-management/rewrite/create/[id]/page.tsx +++ b/app/[locale]/(public)/content-management/rewrite/create/[id]/page.tsx @@ -35,7 +35,7 @@ const imageSchema = z.object({ // tags: z.string().min(1, { message: "Judul diperlukan" }), }); -const page = (props: { states?: any }) => { +const page = (props: { states?: string }) => { const { states } = props; const MySwal = withReactContent(Swal); const router = useRouter(); diff --git a/components/landing-page/hero.tsx b/components/landing-page/hero.tsx index 565e8195..c4b7b0e8 100644 --- a/components/landing-page/hero.tsx +++ b/components/landing-page/hero.tsx @@ -15,6 +15,24 @@ const Hero: React.FC = () => { const [heroData, setHeroData] = useState(); useEffect(() => { + async function fetchCategories() { + const url = 'https://netidhub.com/api/csrf'; + + try { + const response = await fetch(url); + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const data = await response.json(); + return data; // Menampilkan data yang diterima dari API + } catch (error) { + console.error('Fetch error: ', error); + } + } + + fetchCategories(); initFetch(); }, []); const initFetch = async () => { diff --git a/components/partials/auth/login-form.tsx b/components/partials/auth/login-form.tsx index 8be89fc9..cf70b15b 100644 --- a/components/partials/auth/login-form.tsx +++ b/components/partials/auth/login-form.tsx @@ -11,7 +11,7 @@ import { zodResolver } from "@hookform/resolvers/zod"; import { z } from "zod"; import { cn, setCookiesEncrypt } from "@/lib/utils"; import { Loader2 } from "lucide-react"; -import { getProfile, login } from "@/service/auth"; +import { getCsrfToken, getProfile, login } from "@/service/auth"; import { toast } from "sonner"; import { Link, useRouter } from "@/components/navigation"; import { warning } from "@/lib/swal"; @@ -49,12 +49,15 @@ const LoginForm = () => { // Fungsi submit form const onSubmit: SubmitHandler = async (data) => { try { + // const response = null; const response = await login({ ...data, - grant_type: "password", - client_id: "mediahub-app", + grantType: "password", + clientId: "mediahub-app", }); + console.log("LOGIN: ", response); + if (response?.error) { toast.error("Username / Password Tidak Sesuai"); } else { @@ -134,7 +137,6 @@ const LoginForm = () => { ) { if (profile?.data?.data?.userLevel?.id == 761 || profile?.data?.data?.userLevel?.parentLevelId == 761) { window.location.href = "/in/welcome"; - // router.push('/admin/dashboard'); Cookies.set("status", "login", { expires: 1, }); diff --git a/service/auth.ts b/service/auth.ts index 2d03c465..2e02133e 100644 --- a/service/auth.ts +++ b/service/auth.ts @@ -1,6 +1,6 @@ import qs from "qs"; import { getAPIDummy } from "./http-config/axiosCustom"; -import { httpPost } from "./http-config/http-base-service"; +import { httpGet, httpPost } from "./http-config/http-base-service"; import { httpGetInterceptor, httpGetInterceptorWithToken, @@ -8,12 +8,66 @@ import { } from "./http-config/http-interceptor-service"; export async function login(data: any) { + + const res = await getCsrfToken(); + const csrfToken = res?.data?.token; + + + console.log("Token CSRF : ", csrfToken); + const pathUrl = "signin"; const headers = { - 'content-type': 'application/x-www-form-urlencoded', + 'accept': 'application/json', + 'content-type': 'application/json', + 'X-XSRF-TOKEN': csrfToken }; - return httpPost(pathUrl, headers, qs.stringify(data)); + return httpPost(pathUrl, headers, data); +} +// export async function login(data: any, csrfToken: string) { +// const url = 'http://localhost:8080/mediahub/users/signin'; +// try { +// const response = await fetch(url, { +// method: 'POST', +// credentials: 'include', +// headers: { +// 'Content-Type': 'application/json', +// 'X-XSRF-TOKEN': csrfToken || '' +// } +// }); + +// if (!response.ok) { +// throw new Error(`HTTP error! status: ${response.status}`); +// } +// return response; // Menampilkan data yang diterima dari API +// } catch (error) { +// console.error('Fetch error: ', error); +// } +// } + +export async function getCsrfToken() { + const pathUrl = "csrf"; + const headers = { + 'content-type': 'application/json', + }; + return httpGet(pathUrl, headers); + // const url = 'https://netidhub.com/api/csrf'; + // try { + // const response = await fetch(url, { + // method: 'GET', + // credentials: 'include' + // }); + + // if (!response.ok) { + // throw new Error(`HTTP error! status: ${response.status}`); + // } + + // const data = await response.json(); + // console.log("csrf : ", data); + // return data; + // } catch (error) { + // console.error('Fetch error: ', error); + // } } export async function getProfile(token: any) { diff --git a/service/http-config/axios-base-instance.ts b/service/http-config/axios-base-instance.ts index c1c8fb83..e6c5e704 100644 --- a/service/http-config/axios-base-instance.ts +++ b/service/http-config/axios-base-instance.ts @@ -7,6 +7,7 @@ const axiosBaseInstance = axios.create({ headers: { "content-type": "application/json", }, + withCredentials: true, }); export default axiosBaseInstance; diff --git a/service/http-config/axios-interceptor-instance.ts b/service/http-config/axios-interceptor-instance.ts index e02a1102..61c265fc 100644 --- a/service/http-config/axios-interceptor-instance.ts +++ b/service/http-config/axios-interceptor-instance.ts @@ -11,6 +11,7 @@ const axiosInterceptorInstance = axios.create({ headers: { "content-type": "application/json", }, + withCredentials: true, }); // Request interceptor @@ -39,9 +40,9 @@ axiosInterceptorInstance.interceptors.response.use( if (error.response.status === 401 && !originalRequest._retry) { originalRequest._retry = true; const data = { - grant_type: "refresh_token", - refresh_token: refreshToken, - client_id: "mediahub-app", + grantType: "refresh_token", + refreshToken: refreshToken, + clientId: "mediahub-app", }; console.log("refresh token ", data); const res = await login(data);