Skip to content

Commit

Permalink
refactor: Add refreshToken function for handling token refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
seonghunYang committed Jul 16, 2024
1 parent 01d5efa commit e0dfdbf
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 6 deletions.
36 changes: 35 additions & 1 deletion app/business/services/user/user.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { API_PATH } from '../../api-path';
import { SignUpRequestBody, SignInRequestBody, ValidateTokenResponse, UserDeleteRequestBody } from './user.type';
import { httpErrorHandler } from '@/app/utils/http/http-error-handler';
import { BadRequestError, UnauthorizedError } from '@/app/utils/http/http-error';
import { SignUpFormSchema, SignInFormSchema, SignInResponseSchema } from './user.validation';
import {
SignUpFormSchema,
SignInFormSchema,
SignInResponseSchema,
ValidateTokenResponseSchema,
} from './user.validation';
import { cookies } from 'next/headers';
import { isValidation } from '@/app/utils/zod/validation.util';
import { redirect } from 'next/navigation';
Expand Down Expand Up @@ -123,6 +128,35 @@ export async function authenticate(prevState: FormState, formData: FormData): Pr
redirect('/my');
}

export async function refreshToken(): Promise<ValidateTokenResponse | false> {
const refreshToken = cookies().get('refreshToken')?.value;
try {
const response = await fetch(`${API_PATH.auth}/token`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ refreshToken }),
});

const result = await response.json();

httpErrorHandler(response, result);

if (isValidation(result, ValidateTokenResponseSchema)) {
return result;
} else {
throw 'Invalid token response schema.';
}
} catch (error) {
if (error instanceof BadRequestError) {
return false;
} else {
throw error;
}
}
}

export async function createUser(prevState: FormState, formData: FormData): Promise<FormState> {
const validatedFields = SignUpFormSchema.safeParse({
authId: formData.get('authId'),
Expand Down
29 changes: 24 additions & 5 deletions middleware.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { NextRequest } from 'next/server';
import { NextResponse, type NextRequest } from 'next/server';
import { auth } from './app/business/services/user/user.query';
import { isInitUser } from './app/business/services/user/user.validation';
import { refreshToken } from './app/business/services/user/user.command';

async function getAuth(request: NextRequest): Promise<{
role: 'guest' | 'user' | 'init';
role: 'guest' | 'expired' | 'user' | 'init';
}> {
const accessToken = request.cookies.get('accessToken')?.value;
if (!accessToken) {
Expand All @@ -15,10 +16,8 @@ async function getAuth(request: NextRequest): Promise<{
const user = await auth();

if (!user) {
request.cookies.delete('accessToken');
request.cookies.delete('refreshToken');
return {
role: 'guest',
role: 'expired',
};
}

Expand All @@ -42,6 +41,10 @@ function isAllowedGuestPath(path: string, strict: boolean = false) {
export async function middleware(request: NextRequest) {
const auth = await getAuth(request);

if (auth.role === 'expired') {
return await retryAuth(request);
}

if (auth.role === 'init' && !request.nextUrl.pathname.startsWith('/grade-upload')) {
return Response.redirect(new URL('/grade-upload', request.url));
}
Expand All @@ -55,6 +58,22 @@ export async function middleware(request: NextRequest) {
}
}

async function retryAuth(request: NextRequest) {
const response = NextResponse.redirect(request.url);
const result = await refreshToken();
if (result === false) {
response.cookies.delete('accessToken');
response.cookies.delete('refreshToken');
} else {
response.cookies.set('accessToken', result.accessToken, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
path: '/',
});
}
return response;
}

export const config = {
matcher: ['/((?!api|mockServiceWorker|_next/static|_next/image|.*\\.png$).*)'],
};

0 comments on commit e0dfdbf

Please sign in to comment.