diff --git a/src/components/ProtectedRoute.tsx b/src/components/ProtectedRoute.tsx
index b0e86f8..d47993e 100644
--- a/src/components/ProtectedRoute.tsx
+++ b/src/components/ProtectedRoute.tsx
@@ -1,19 +1,10 @@
-import React, { ReactNode } from 'react';
+import React from 'react';
import { Navigate } from 'react-router-dom';
import Cookies from 'js-cookie';
-interface ProtectedProps {
- children: ReactNode;
-}
-
-const ProtectedRoute = ({ children }: ProtectedProps) => {
- const userCookie = Cookies.get("SYS-REFRESH");
-
- if (!userCookie) {
- return ;
- }
-
- return children;
+const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
+ const refreshToken = Cookies.get("refresh_token");
+ return refreshToken ? children : ;
};
-export default ProtectedRoute;
+export default ProtectedRoute;
\ No newline at end of file
diff --git a/src/services/AuthService.ts b/src/services/AuthService.ts
index 972b62e..c53f82e 100644
--- a/src/services/AuthService.ts
+++ b/src/services/AuthService.ts
@@ -1,81 +1,89 @@
-import { LoginFormData, AuthResponse } from "../types/Auth";
+import Cookies from 'js-cookie';
+
+import { AuthResponse, UserProfile } from "../types/Auth";
import { AuthType } from "./dto/request/AuthType";
import { LoginRequest } from "./dto/request/LoginRequest";
import { loginRequestViaApp } from "./dto/request/LoginRequestViaApp";
import { loginRequestViaPin } from "./dto/request/LoginRequestViaPin";
-import { RequestType } from "./dto/request/RequestType";
-import { LoginResponse } from "./dto/response/LoginResponse";
import SERVICE_API_URL from "./ServiceEndPoint";
const BASE_URL = SERVICE_API_URL.BASE_URL;
export class AuthService {
- static async execute(data: LoginRequest): Promise {
- let endpoint = "";
-
- if (data.requestType === RequestType.DASHBOARD &&data.authType === AuthType.APP) {
- endpoint = `${BASE_URL}/auth/app-login`;
- } else if (data.requestType === RequestType.DASHBOARD && data.authType === AuthType.PIN) {
- endpoint = `${BASE_URL}/auth/login`;
- } else if (data.requestType === RequestType.OAUTH &&data.authType === AuthType.APP) {
- endpoint = `${BASE_URL}/oauth/app-login`;
- } else {
- endpoint = `${BASE_URL}/oauth/login`;
- }
-
- console.log(endpoint);
- console.log(data);
-
- const requestBody = this.getRequestDtoByAuthType(data);
+ static async login(data: LoginRequest): Promise {
+ const endpoint = `${BASE_URL}/auth/login`;
+ const requestBody = this.buildRequestBody(data);
const response = await fetch(endpoint, {
method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
+ headers: { "Content-Type": "application/json" },
body: JSON.stringify(requestBody),
- mode: 'cors',
});
const result = await response.json();
-
+
if (!response.ok) {
- throw new Error(result.message || "로그인 중 오류가 발생했습니다.");
- }
-
- if (data.requestType !== RequestType.DASHBOARD) {
- this.handleOAuthSuccess(result, data.redirectUrl);
- return;
+ throw new Error(result.message || "로그인 실패");
}
this.storeTokens(result);
window.location.href = data.redirectUrl;
}
- private static getRequestDtoByAuthType(data: LoginRequest): any {
- if (data.authType === AuthType.APP) {
- return loginRequestViaApp(data);
- } else {
- return loginRequestViaPin(data);
- }
+ static async reissueToken(): Promise {
+ const refreshToken = Cookies.get("refresh_token");
+ if (!refreshToken) throw new Error("No refresh token");
+
+ const response = await fetch(`${BASE_URL}/auth/reissue`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ refreshToken }),
+ });
+
+ const result = await response.json();
+ if (!response.ok) throw new Error(result.message || "토큰 재발급 실패");
+
+ this.storeTokens(result);
+ return result;
}
- private static handleOAuthSuccess(result: any, redirectUrl?: string): void {
- if (!redirectUrl) {
- throw new Error("리디렉션 URL이 필요합니다.");
- }
+ // 사용자 프로필 조회
+ static async getProfile(): Promise {
+ const response = await this.authFetch(`${BASE_URL}/auth/userinfo`);
+ return response.json();
+ }
- const authCode = result.code;
- if (!authCode) {
- throw new Error("응답에 인증 코드가 포함되어 있지 않습니다.");
+ // 인증된 요청 처리 래퍼
+ private static async authFetch(input: RequestInfo, init?: RequestInit): Promise {
+ let accessToken = Cookies.get("access_token");
+ let response = await fetch(input, {
+ ...init,
+ headers: { ...init?.headers, Authorization: `Bearer ${accessToken}` },
+ });
+
+ if (response.status === 401) {
+ await this.reissueToken();
+ accessToken = Cookies.get("access_token");
+ response = await fetch(input, {
+ ...init,
+ headers: { ...init?.headers, Authorization: `Bearer ${accessToken}` },
+ });
}
+ return response;
+ }
- const redirectWithAuthCode = `${redirectUrl}?AUTH_CODE=${authCode}`;
- window.location.href = redirectWithAuthCode;
+ private static buildRequestBody(data: LoginRequest) {
+ if (data.authType === AuthType.APP) {
+ // loginRequestViaApp 사용
+ return loginRequestViaApp(data);
+ } else {
+ // loginRequestViaPin 사용
+ return loginRequestViaPin(data);
+ }
}
- private static storeTokens(result: LoginResponse): void {
- document.cookie = `access_token=${result.access_token}; path=/; secure; HttpOnly`;
- document.cookie = `refresh_token=${result.refresh_token}; path=/; secure; HttpOnly`;
+ private static storeTokens(tokens: AuthResponse) {
+ Cookies.set("access_token", tokens.access_token, { secure: true, expires: 1 });
+ Cookies.set("refresh_token", tokens.refresh_token, { secure: true, expires: 7 });
}
}
diff --git a/src/services/RegisterService.ts b/src/services/RegisterService.ts
index 164933f..6a2578a 100644
--- a/src/services/RegisterService.ts
+++ b/src/services/RegisterService.ts
@@ -3,44 +3,24 @@ const BASE_URL = SERVICE_API_URL.BASE_URL;
export class RegisterService {
static async register(data: {
- redirectUrl?: string;
email: string;
password: string;
name: string;
birthDate: string;
pin: string;
- }): Promise {
+ redirectUrl?: string;
+ }) {
const deviceToken = window.nanu_androidgw?.devicetoken || "WEB_NONE";
- const requestBody = {
- deviceToken: deviceToken,
- pin: data.pin,
- password: data.password,
- name: data.name,
- email: data.email,
- birthDate: data.birthDate,
- };
-
- const endpoint = `${BASE_URL}/auth/register`;
-
- const response = await fetch(endpoint, {
+
+ const response = await fetch(`${BASE_URL}/auth/register`, {
method: "POST",
- headers: {
- "Content-Type": "application/json",
- },
- body: JSON.stringify(requestBody),
- mode: "cors",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ ...data, deviceToken }),
});
const result = await response.json();
+ if (!response.ok) throw new Error(result.message || "회원가입 실패");
- if (!response.ok) {
- throw new Error(result.message || "회원가입 중 오류가 발생했습니다.");
- }
-
- if (data.redirectUrl) {
- window.location.href = data.redirectUrl;
- } else {
- window.location.href = "/home";
- }
+ window.location.href = data.redirectUrl || "/login";
}
-}
+}
\ No newline at end of file
diff --git a/src/types/Auth.ts b/src/types/Auth.ts
index 83de863..936838f 100644
--- a/src/types/Auth.ts
+++ b/src/types/Auth.ts
@@ -5,13 +5,11 @@ export interface LoginFormData {
}
export interface AuthResponse {
- token: string;
- user: {
- id: string;
- email: string;
- };
+ access_token: string;
+ refresh_token: string;
}
+
export interface RegisterFormData {
email: string;
password: string;
@@ -22,3 +20,9 @@ export interface RegisterFormData {
confirmPin: string;
termsAccepted: boolean;
}
+
+export interface UserProfile {
+ email: string;
+ name: string;
+ accountStatus: boolean;
+}
\ No newline at end of file