-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
80 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 }); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters