Skip to content

Commit

Permalink
chore : api 연동
Browse files Browse the repository at this point in the history
  • Loading branch information
0xC0FFE2 committed Feb 4, 2025
1 parent cbe9951 commit b366425
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 97 deletions.
19 changes: 5 additions & 14 deletions src/components/ProtectedRoute.tsx
Original file line number Diff line number Diff line change
@@ -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 <Navigate to="/login" replace />;
}

return children;
const ProtectedRoute = ({ children }: { children: React.ReactNode }) => {
const refreshToken = Cookies.get("refresh_token");
return refreshToken ? children : <Navigate to="/login" replace />;
};

export default ProtectedRoute;
export default ProtectedRoute;
106 changes: 57 additions & 49 deletions src/services/AuthService.ts
Original file line number Diff line number Diff line change
@@ -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<void> {
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<void> {
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<AuthResponse> {
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<UserProfile> {
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<Response> {
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 });
}
}
38 changes: 9 additions & 29 deletions src/services/RegisterService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<void> {
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";
}
}
}
14 changes: 9 additions & 5 deletions src/types/Auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -22,3 +20,9 @@ export interface RegisterFormData {
confirmPin: string;
termsAccepted: boolean;
}

export interface UserProfile {
email: string;
name: string;
accountStatus: boolean;
}

0 comments on commit b366425

Please sign in to comment.