11import { NextRequest , NextResponse } from "next/server" ;
22import axios from "axios" ;
33import { decodeJwt } from "@/middleware" ;
4- import { OauthUser } from "@/types/oauth/oauthReq" ;
54import apiClient from "@/lib/apiClient" ;
5+ import { OauthLoginUser , OauthResponse , OauthSignupUser } from "@/types/oauth/oauth" ;
6+ import { cookies } from "next/headers" ;
67
7- export const GET = async ( req : NextRequest ) => {
8- const searchParams = req . nextUrl . searchParams ;
8+ export const GET = async ( request : NextRequest ) => {
9+ const searchParams = request . nextUrl . searchParams ;
910 const code = searchParams . get ( "code" ) ;
1011 const state = searchParams . get ( "state" ) ;
1112
12- if ( ! code ) {
13- return NextResponse . json ( { message : "Code not found" } , { status : 400 } ) ;
13+ if ( ! code || ! state ) {
14+ return NextResponse . json ( { message : ` ${ ! code ? "Code" : "State" } not found` } , { status : 400 } ) ;
1415 }
1516
16- if ( ! state ) {
17- return NextResponse . json ( { message : "State not found" } , { status : 400 } ) ;
18- }
19-
20- // `state`를 JSON으로 파싱
2117 let parsedState ;
2218 try {
2319 parsedState = JSON . parse ( decodeURIComponent ( state ) ) ;
24- } catch ( error ) {
25- console . error ( "Failed to parse state:" , error ) ;
20+ } catch {
2621 return NextResponse . json ( { message : "Invalid state format" } , { status : 400 } ) ;
2722 }
2823
29- const { provider, role } = parsedState ;
30-
24+ const { provider, action, role } = parsedState ;
3125 const GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token" ;
3226 const clientId = process . env . NEXT_PUBLIC_GOOGLE_CLIENT_ID ;
3327 const clientSecret = process . env . NEXT_PUBLIC_GOOGLE_SECRET ;
@@ -38,8 +32,8 @@ export const GET = async (req: NextRequest) => {
3832 }
3933
4034 try {
41- // Access Token 요청
42- const tokenResponse = await axios . post ( GOOGLE_TOKEN_URL , null , {
35+ // Google Access Token 요청
36+ const { data : tokenResponse } = await axios . post ( GOOGLE_TOKEN_URL , null , {
4337 params : {
4438 code,
4539 client_id : clientId ,
@@ -49,41 +43,76 @@ export const GET = async (req: NextRequest) => {
4943 } ,
5044 } ) ;
5145
52- const { id_token } = tokenResponse . data ;
53-
54- // id_token 디코딩
46+ const { id_token } = tokenResponse ;
5547 const decodedIdToken = decodeJwt ( id_token ) ;
5648 if ( ! decodedIdToken ) {
5749 return NextResponse . json ( { message : "Invalid ID token" } , { status : 400 } ) ;
5850 }
5951
60- const googleUser : OauthUser = {
61- role : role ,
62- name : decodedIdToken . name ,
63- token : id_token ,
52+ const googleUser : { signup : OauthSignupUser ; login : OauthLoginUser } = {
53+ signup : {
54+ role,
55+ name : decodedIdToken . name ,
56+ token : id_token ,
57+ } ,
58+ login : {
59+ token : id_token ,
60+ redirectUri,
61+ } ,
6462 } ;
65- console . log ( "Google user:" , googleUser ) ;
66- // OAuth 회원가입 API로 회원가입 요청
67- try {
68- const googleSignupResponse = await apiClient . post ( `/oauth/sign-up/${ provider } ` , googleUser ) ;
69- console . log ( "구글 회원가입 성공:" , googleSignupResponse . data ) ;
70- } catch ( error ) {
71- const errorMessage = ( error as any ) . response ?. data ;
72- console . error ( "구글 회원가입 에러:" , errorMessage ) ;
73- }
7463
75- // 사용자 정보를 클라이언트에 반환
76- const response = NextResponse . redirect ( "http://localhost:3000" ) ;
77- response . cookies . set ( "user" , JSON . stringify ( googleUser ) , {
78- httpOnly : true ,
79- secure : process . env . NODE_ENV === "production" ,
80- sameSite : "strict" ,
81- maxAge : 60 * 60 * 24 , // 1일
82- path : "/" ,
83- } ) ;
84- return response ;
85- } catch ( error ) {
86- console . error ( "Google login error:" , error ) ;
87- return NextResponse . json ( { message : "서버에러" } , { status : 500 } ) ;
64+ const processUser = async ( ) => {
65+ if ( action === "signup" ) {
66+ try {
67+ const response = await apiClient . post < OauthResponse > ( `/oauth/sign-up/${ provider } ` , googleUser . signup ) ;
68+ console . log ( "구글 회원가입 성공:" , response . data ) ;
69+ } catch ( error : any ) {
70+ if ( error . response ?. status === 400 ) {
71+ console . log ( "이미 등록된 사용자입니다. 로그인 시도 중..." ) ;
72+ await loginUser ( ) ;
73+ } else {
74+ throw new Error ( "회원가입 중 서버 오류" ) ;
75+ }
76+ }
77+ } else if ( action === "login" ) {
78+ await loginUser ( ) ;
79+ } else {
80+ throw new Error ( "잘못된 작업 에러" ) ;
81+ }
82+ } ;
83+
84+ const loginUser = async ( ) => {
85+ const { data : loginResponse } = await axios . post < OauthResponse > (
86+ `${ process . env . NEXT_PUBLIC_DOMAIN_URL } /api/oauth/login/${ provider } ` ,
87+ googleUser . login
88+ ) ;
89+ console . log ( "구글 로그인 성공:" , loginResponse ) ;
90+
91+ // 쿠키 저장
92+ const { accessToken, refreshToken } = loginResponse ;
93+ setCookies ( accessToken , refreshToken ) ;
94+ } ;
95+
96+ const setCookies = ( accessToken : string , refreshToken : string ) => {
97+ cookies ( ) . set ( "accessToken" , accessToken , {
98+ httpOnly : true ,
99+ secure : process . env . NODE_ENV === "production" ,
100+ sameSite : "lax" ,
101+ path : "/" ,
102+ } ) ;
103+ cookies ( ) . set ( "refreshToken" , refreshToken , {
104+ httpOnly : true ,
105+ secure : process . env . NODE_ENV === "production" ,
106+ sameSite : "lax" ,
107+ path : "/" ,
108+ } ) ;
109+ } ;
110+
111+ await processUser ( ) ;
112+ } catch ( error : any ) {
113+ console . error ( "OAuth 처리 중 오류:" , error . message || error ) ;
114+ return NextResponse . json ( { message : error . message || "서버 오류" } , { status : 500 } ) ;
88115 }
116+
117+ return NextResponse . redirect ( new URL ( "/" , request . url ) ) ;
89118} ;
0 commit comments