로그인 테스트 작업중

This commit is contained in:
leedj312
2025-07-17 15:57:20 +09:00
parent bd6dfd31fd
commit 5f302a5711
13 changed files with 407 additions and 16 deletions
+32
View File
@@ -0,0 +1,32 @@
import { cmsPostFectch } from "@/components/lib/api";
export const isLogin = async () => {
const headers = {
accept: "application/json",
"Content-Type": "application/json",
"X-Site-Id": "WR",
"Access-Control-Expose-Headers" : ["Authorization","refresh-token","token-id"]
};
const param = { userId: "tuser10003", password: "test1234!" };
await cmsPostFectch("/user-service/login",param,headers);
};
// export type LoginState = {
// login: {} as any;
// };
// export type loginType = LoginState & LoginActions;
// export const loginState: LoginState = {
// login: {},
// };
// export type LoginActions = {
// isLogin: () => void;
// };
// export const loginActionExport: (set: any) => LoginActions = (set: any) => {
// return {
// isLogin: async () => {},
// };
// };
+3
View File
@@ -96,6 +96,8 @@ import {
} from "./ruseFcltMng/fcltSttn/rswtSttn";
import { rainStatActionsExport, rainStatExport, type rainStatState, type rainStatType } from "./stats/rainStat";
import { rswtStatActionsExport, rswtStatExport, type rswtStatState, type rswtStatType } from "./stats/rswtStat";
//import { isLogin } from "./common/login";
import { LoginApi } from "@/src/entities/auth";
export type WrStore = comCodeType &
pubFacType &
@@ -188,6 +190,7 @@ export const StoreZus = (
getMiddleRegionCd(set);
getUnitWaterShedCd(set);
getEnvPartCd(set);
LoginApi.login({userId: "tuser10003", password: "test1234!"})
return {
...initState,
...comFcltSearchAction(set),
+18
View File
@@ -108,6 +108,24 @@ export const postFectch = async (url: string, params: any, type?: string) => {
return await response.json();
};
export const cmsPostFectch = async (url: string, params: any,headers:any) => {
const response = fetch(url, {
method: "POST",
headers:headers ,
body: JSON.stringify(params),
}).then((res) =>
{
console.log(' res ' , res)
console.log(' access-token ' , res.headers.get('access-token'))
console.log(' refresh-token ' , res.headers.get('refresh-token'))
console.log(' token-id ' , res.headers.get('token-id'))
})
return await response;
};
export const putFectch = async (url: string, params: any,type?:string) => {
const div =
type === fetchType.COMMON
+88
View File
@@ -0,0 +1,88 @@
import {
initValInUsage,
initValOutUsage,
subTotalObj,
totalObj,
type PrfType,
type PrfUsageSummary,
} from "@/app/store/prfmncReg/pbnstPrfmncReg/type";
export const getTablePrfData = (prfList: PrfType[]) => {
const inUsageData = structuredClone(initValInUsage);
const outUsageData = structuredClone(initValOutUsage);
const inSubtotal = structuredClone(subTotalObj);
const outSubtotal = structuredClone(subTotalObj);
if (prfList) {
prfList?.forEach((prfItem) => {
const month = Number(prfItem?.ym?.slice(4)); // "MM"
const monthKey = `${month}월`;
inUsageData.forEach((inData: PrfUsageSummary) => {
const usageKey = inData.usage as keyof PrfType;
const value = (prfItem[usageKey] as number) ?? 0;
(inData[monthKey as keyof PrfUsageSummary] as number) = value;
inData.total += value;
if (inSubtotal&& usageKey !== "subtotal" as keyof PrfType) {
(inSubtotal[monthKey as keyof PrfUsageSummary] as number) =
((inSubtotal[monthKey as keyof PrfUsageSummary] as number) ?? 0) +
value;
inSubtotal.total += value;
}
});
outUsageData.forEach((outData: PrfUsageSummary) => {
const usageKey = outData.usage as keyof PrfType;
const value = (prfItem[usageKey] as number) ?? 0; // Type assertion for prfItem[usageKey]
(outData[monthKey as keyof PrfUsageSummary] as number) = value;
outData.total += value;
if (outSubtotal && usageKey !== "subtotal" as keyof PrfType) {
(outSubtotal [monthKey as keyof PrfUsageSummary] as number) =
((outSubtotal[monthKey as keyof PrfUsageSummary] as number) ?? 0) + value;
outSubtotal.total += value;
} // End of if (outSubtotal && usageKey !== "subtotal")
}); // End of outUsageData.forEach
});
(inSubtotal as any)["구분"] = "장내용수";
(outSubtotal as any)["구분"] = "장내용수";
inUsageData.push(inSubtotal);
outUsageData.push(outSubtotal);
const usageTotalObj: { [key: string]: any } = structuredClone(totalObj);
for (const key in usageTotalObj) {
if (["usage", "gubun", "edit"].includes(key)) continue;
const val =
(Number((inSubtotal as any)[key]) || 0) +
(Number((outSubtotal as any)[key]) || 0);
(usageTotalObj as any)[key] = val;
}
const tableData = [...inUsageData, ...outUsageData, usageTotalObj];
return {
inPrf: inUsageData,
outPrf: outUsageData,
totalPrf: tableData,
};
}
};
// const usageKey = inData.usage as keyof PrfType;
// const value = (prfItem[usageKey] as number) ?? 0;
// (inData[monthKey as keyof PrfUsageSummary] as number) = value;
// inData.total += value;
// if (inSubtotal&& usageKey !== "subtotal" as keyof PrfType) {
// (inSubtotal[monthKey as keyof PrfUsageSummary] as number) =
// ((inSubtotal[monthKey as keyof PrfUsageSummary] as number) ?? 0) +
// value;
// inSubtotal.total += value;
// }
+38 -16
View File
@@ -1,10 +1,10 @@
import { NextRequest, NextResponse } from "next/server";
import { CS_URL } from "./components/lib/config";
//import { CLAIM_NAME, AUTH_USER_ID } from "./src/shared/config";
import { CLAIM_NAME, AUTH_USER_ID } from "./src/shared/config";
const CLAIM_NAME = "Authorization";
const AUTH_USER_ID = "token-id";
const serverApiUrl = CS_URL;
// const CLAIM_NAME = "Authorization";
// const AUTH_USER_ID = "token-id";
const serverApiUrl = CS_URL;
const GEOSERVER_URL = process.env.NEXT_PUBLIC_GEOSERVER_URL || "";
const LX_GEOSERVER_URL = process.env.NEXT_PUBLIC_LX_GEOSERVER_URL || "";
const SEWERAGE_API_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL || "";
@@ -14,28 +14,38 @@ export function middleware(req: NextRequest) {
console.log(`[Middleware] Request URL: ${req.url}`);
const searchParams = req.nextUrl.searchParams;
// if (pathname.startsWith("/server")) {
// const queryParams = searchParams.toString();
// const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${
// queryParams ? `?${queryParams}` : ""
// }`;
// console.log(`[Middleware] Rewriting from '/server' path to: ${newUrl}`);
// return NextResponse.rewrite(new URL(newUrl));
// }
if (pathname.startsWith("/server")) {
const queryParams = searchParams.toString();
const decodedParams = Array.from(searchParams.entries())
.map(([key, value]) => `${key}=${decodeURIComponent(value)}`)
.join("&");
console.log(' sesesesesesevereveraserwereqwrewbrtkehjwrtg server')
const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${
queryParams ? `?${queryParams}` : ""
decodedParams ? `?${decodedParams}` : ""
}`;
console.log(`[Middleware] Rewriting from '/server' path to: ${newUrl}`);
return NextResponse.rewrite(new URL(newUrl));
}
if (pathname.startsWith("/attach-service")) {
const requestHeaders = new Headers(req.headers);
const token =
"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJtbmdyWW4iOiJZIiwiZXhwIjoxNzQ4ODQ4NDkxfQ.ZiYpKxAMyyoPuUquxsWxfQbMBzYN4tsa7itZ49_OEsdGvbUUmKzrIV6Or7VVbEjtAqhh7W97nqB5EP6GRzFC9Q";
const userId = "a0ec7a07-752a-4f7f-89a6-854e63d2e3a0";
//const token = req.cookies.get(CLAIM_NAME)?.value;
//const userId = req.cookies.get(AUTH_USER_ID)?.value;
// const token =
// "eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhMGVjN2EwNy03NTJhLTRmN2YtODlhNi04NTRlNjNkMmUzYTAiLCJhdXRob3JpdGllcyI6IlJPTEVfQURNSU4sUk9MRV9BTk9OWU1PVVMiLCJtbmdyWW4iOiJZIiwiZXhwIjoxNzUyMTM1OTk3fQ.itGY6M6mC2iwKvEpXw2KS6354T_B_OFz4hD26ResIgwJhpwiDJCMuSXD-rZ3AarmAIKd0udpCuJR7UlvFMN2ww";
// const userId = "a0ec7a07-752a-4f7f-89a6-854e63d2e3a0";
const token = req.cookies.get(CLAIM_NAME)?.value;
const userId = req.cookies.get(AUTH_USER_ID)?.value;
const newUrl = `${serverApiUrl}${pathname}`;
console.log("serverApiUrl ", serverApiUrl);
console.log("pathname ", pathname);
//wr:dev: pathname /attach-service/api/v1/tus/upload/5e60b70a-956e-40c3-be5a-cdd3100bf8ad
//http://dev.onasys.co.kr:8000/attach-service/api/v1/tus/upload/5e60b70a-956e-40c3-be5a-cdd3100bf8ad
if (token) requestHeaders.set(CLAIM_NAME, token);
if (userId) requestHeaders.set(AUTH_USER_ID, userId);
@@ -48,6 +58,18 @@ export function middleware(req: NextRequest) {
});
}
if (pathname.startsWith("/user-service")) {
const requestHeaders = new Headers(req.headers);
const newUrl = `${serverApiUrl}${pathname}`;
console.log(
`[Middleware] Rewriting from '/user-service' path to: ${newUrl}`
);
return NextResponse.rewrite(new URL(newUrl), {
headers: requestHeaders
});
}
if (pathname.startsWith("/geoserver")) {
let queryParams = searchParams.toString();
const typename = searchParams.get("TYPENAME");
@@ -103,5 +125,5 @@ export function middleware(req: NextRequest) {
}
export const config = {
matcher: ["/server/:path*", "/attach-service/:path*", "/geoserver/:path*", "/sewerage-service/:path*"],
matcher: ["/server/:path*", "/user-service/:path*", "/attach-service/:path*", "/geoserver/:path*", "/sewerage-service/:path*"],
};
+1
View File
@@ -17,6 +17,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"i18next": "^25.3.2",
"js-cookie": "^3.0.5",
"lucide-react": "^0.474.0",
"moment": "^2.30.1",
"next": "15.1.7",
@@ -0,0 +1,80 @@
import type { LoginService, ILogin } from "../model/login-interface";
import { tokenManager } from "../lib/token-manager";
import {PROXY_HOST, ACCESS_TOKEN, AUTH_USER_ID,SITE_ID, CLAIM_NAME, ENDPOINT, JWT_EXPIRATION_TIME } from "../../../shared/config";
export class LoginApiService implements LoginService {
private static instance: LoginApiService;
private constructor() {}
public static getInstance(): LoginApiService {
if (!LoginApiService.instance) {
LoginApiService.instance = new LoginApiService();
}
return LoginApiService.instance;
}
public async login(payload: ILogin): Promise<void> {
try {
console.log(' ENDPOINT.USER_SERVICE.LOGIN ', ENDPOINT.USER_SERVICE.LOGIN)
const response = await fetch( PROXY_HOST+ ENDPOINT.USER_SERVICE.LOGIN, {
method: "POST",
body: JSON.stringify({
userId: payload.userId,
password: payload.password,
}),
});
// const data = response.headers.get(ACCESS_TOKEN);
const accessToken = response.headers.get(ACCESS_TOKEN);
const tokenId = response.headers.get(AUTH_USER_ID);
console.log('accessToken ', accessToken)
console.log('tokenId ', tokenId)
if (!accessToken || !tokenId) {
throw new Error("Missing required authentication tokens");
}
tokenManager.setToken(CLAIM_NAME, accessToken);
tokenManager.setToken(AUTH_USER_ID, tokenId);
tokenManager.setToken("site-id-key", SITE_ID);
tokenManager.setupRefreshTimer(
() => this.silentRefresh(),
JWT_EXPIRATION_TIME,
);
} catch (error) {
console.log(' login err ' , error)
throw new Error(`Login failed: ${error}`);
}
}
public async silentRefresh(): Promise<void> {
console.log(' silentRefresh ')
try {
const response = await fetch(PROXY_HOST+
`${ENDPOINT.USER_SERVICE.SILENT_REFRESH}`,
{ method: "PUT" },
);
const data = await response.json();
const accessToken = data[ACCESS_TOKEN];
const tokenId = data[AUTH_USER_ID];
if (!accessToken || !tokenId) {
throw new Error("Missing required authentication tokens");
}
tokenManager.setToken(CLAIM_NAME, accessToken);
tokenManager.setToken(AUTH_USER_ID, tokenId);
} catch (error) {
tokenManager.clearAuthToken();
throw new Error(`Silent refresh failed: ${error}`);
}
}
}
export const LoginApi = LoginApiService.getInstance();
+2
View File
@@ -0,0 +1,2 @@
export { LoginApi } from "./api/login-service";
//export { AuthWrapper } from "./lib/auth-wrapper";
@@ -0,0 +1,45 @@
// "use client";
// import { useEffect } from "react";
// import { useRouter } from "next/navigation";
// import { LoginApi } from "../api/login-service";
// const AuthWrapper = ({ children }: { children: React.ReactNode }) => {
// const router = useRouter();
// const { userInfo, setUserInfo } = useUserStore((state) => state);
// async function authCheck() {
// const userId = getCookie(AUTH_USER_ID);
// if (!userId) {
// throw new Error("Missing required authentication tokens");
// }
// const response = await client.get<IUserInfo>(
// `${ENDPOINT.USER_SERVICE.USERS}/info/me`,
// );
// if (!userInfo) setUserInfo(response.data);
// }
// useEffect(() => {
// (async () => {
// try {
// await authCheck();
// } catch (error) {
// console.error(error);
// try {
// await LoginApi.silentRefresh();
// await authCheck();
// } catch (refreshError) {
// console.error("Token refresh failed:", refreshError);
// setUserInfo(null);
// router.push("/auth/login");
// }
// }
// })();
// }, []);
// return <>{children}</>;
// };
// export { AuthWrapper };
@@ -0,0 +1,59 @@
import { AUTH_USER_ID, CLAIM_NAME } from "@/src/shared/config";
import { getCookie, removeCookie, setCookie } from "@/src/shared/lib/cookie";
export class TokenManager {
private static instance: TokenManager;
private refreshTimer: NodeJS.Timeout | null = null;
private constructor() {}
public static getInstance(): TokenManager {
if (!TokenManager.instance) {
TokenManager.instance = new TokenManager();
}
return TokenManager.instance;
}
public getToken(key: string): string | undefined {
return getCookie(key);
}
public setToken(key: string, value: string): void {
setCookie(key, value, {
secure: window.location.protocol === "https:",
sameSite: "lax",
});
}
public removeToken(key: string): void {
removeCookie(key);
}
public setupRefreshTimer(
callback: () => Promise<void>,
expirationTime: number,
): void {
if (this.refreshTimer) {
clearTimeout(this.refreshTimer);
}
this.refreshTimer = setTimeout(() => {
callback().catch((error) => {
console.error("Silent refresh failed:", error);
this.clearAuthToken();
});
}, expirationTime - 60000);
}
public clearAuthToken(): void {
if (this.refreshTimer) {
clearTimeout(this.refreshTimer);
this.refreshTimer = null;
}
this.removeToken(CLAIM_NAME);
this.removeToken(AUTH_USER_ID);
}
}
export const tokenManager = TokenManager.getInstance();
@@ -0,0 +1,9 @@
export interface ILogin {
userId: string;
password: string;
}
export interface LoginService {
login(payload: ILogin): Promise<void>;
silentRefresh(): Promise<void>;
}
+1
View File
@@ -12,3 +12,4 @@ export const AUTH_USER_ID = process.env.NEXT_PUBLIC_AUTH_USER_ID || "token-id";
export const SERVER_SEWERAGE_API_URL = process.env.NEXT_PUBLIC_SEWERAGE_API_URL;
+31
View File
@@ -0,0 +1,31 @@
import Cookies from "js-cookie";
export function getCookie(name: string): string | undefined {
if (typeof window === "undefined") {
return undefined;
}
return Cookies.get(name);
}
export function setCookie(
name: string,
value: string,
options?: Cookies.CookieAttributes,
): void {
if (typeof window === "undefined") {
return;
}
Cookies.set(name, value, options);
}
export function removeCookie(
name: string,
options?: Cookies.CookieAttributes,
): void {
if (typeof window === "undefined") {
return;
}
Cookies.remove(name, options);
}