| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- 'use server';
- import { cookies } from 'next/headers';
- import { fetchJson, getAccessToken, getRefreshToken } from '@/lib/utils/server';
- import { MemberResponse } from '@/types/response/account/member';
- import { LoginResponse } from '@/types/response/auth';
- // RefreshToken으로 AccessToken 갱신
- // 백엔드가 Set-Cookie 를 보내지 않으므로 응답 body 의 새 토큰을 직접 쿠키에 set.
- // 이게 빠지면 cookie 의 구 refreshToken 이 갱신되지 않아 grace period(30s) 만료 시 재사용 탐지로 강제 로그아웃됨.
- async function refreshAccessToken(): Promise<boolean>
- {
- const refreshToken = await getRefreshToken();
- if (!refreshToken) {
- return false;
- }
- const res = await fetchJson<LoginResponse>('/api/auth/refresh-token', {
- method: 'POST',
- body: JSON.stringify({ RefreshToken: refreshToken })
- });
- if (!res.success || !res.data) {
- return false;
- }
- const cookieStore = await cookies();
- const sevenDaysSec = 7 * 24 * 60 * 60;
- const opts = {
- httpOnly: true,
- path: '/',
- sameSite: 'lax' as const,
- secure: process.env.NODE_ENV === 'production',
- maxAge: sevenDaysSec
- };
- cookieStore.set('accessToken', res.data.accessToken, opts);
- cookieStore.set('refreshToken', res.data.refreshToken, opts);
- return true;
- }
- // 로그인 확인
- export async function checkAuthServer(): Promise<boolean>
- {
- const accessToken = await getAccessToken();
- if (accessToken) {
- try {
- const payload = JSON.parse(
- Buffer.from(accessToken.split('.')[1], 'base64').toString()
- );
- if (payload.exp * 1000 > Date.now()) {
- return true;
- }
- } catch {
- }
- }
- return await refreshAccessToken();
- }
- // SSR 초기 회원 정보 조회 (헤더 깜빡임 방지용)
- export async function getInitialMember(): Promise<MemberResponse|null>
- {
- const accessToken = await getAccessToken();
- if (!accessToken) {
- return null;
- }
- try {
- const payload = JSON.parse(
- Buffer.from(accessToken.split('.')[1], 'base64').toString()
- );
- if (payload.exp * 1000 <= Date.now()) {
- return null;
- }
- } catch {
- return null;
- }
- const res = await fetchJson<MemberResponse>('/api/auth/profile', {
- method: 'GET'
- });
- if (res.success && res.data) {
- return res.data;
- }
- return null;
- }
|