diff --git a/src/backend/auth-server/main.ts b/src/backend/auth-server/main.ts index 0f24a06a..8cc5d839 100644 --- a/src/backend/auth-server/main.ts +++ b/src/backend/auth-server/main.ts @@ -137,6 +137,12 @@ app.register(fastifySwaggerUi, { app.register(currentAuthPlugin); app.register(routes); +app.register(cors, { + origin: false, + credentials: true, + allowedHeaders: ['Content-Type', 'Authorization', 'Refresh-Token'], +}); + app .register(fastifyRedis, { client: redis, @@ -151,6 +157,13 @@ app app.register(fastifyCookie, { secret: SECRET_KEY, + hook: 'onRequest', + parseOptions: { + secure: true, + httpOnly: true, + sameSite: 'none', + path: '/', + }, } as FastifyCookieOptions); app.setErrorHandler((err, req, reply) => { diff --git a/src/backend/auth-server/src/controllers/auth/index.ts b/src/backend/auth-server/src/controllers/auth/index.ts index 9cb461f1..7f7a474d 100644 --- a/src/backend/auth-server/src/controllers/auth/index.ts +++ b/src/backend/auth-server/src/controllers/auth/index.ts @@ -1,5 +1,5 @@ import { FastifyRequest, FastifyReply } from 'fastify'; -import { generateHash } from '../../libs/authHelper'; +import { generateHash, shortVerifyRefreshToken } from '../../libs/authHelper'; import { ERROR_MESSAGE, REDIS_KEY } from '../../libs/constants'; import { SUCCESS_MESSAGE } from '../../libs/constants'; import { handleError } from '../../libs/errorHelper'; @@ -23,16 +23,9 @@ function authController() { return; } - res.setCookie('refresh_token', values.refreshToken, { - sameSite: true, - httpOnly: true, - secure: true, - path: '/', - expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7), - }); - const result = { accessToken: values.accessToken, + refreshToken: values.refreshToken, }; await redis.set(REDIS_KEY.refreshToken(values.id), values.refreshToken); @@ -67,33 +60,6 @@ function authController() { } }; - const mobileLogin = async (req: FastifyRequest, res: FastifyReply) => { - const { email, password } = req.body as { email: string; password: string }; - - const values = await authService.loginWithPassword(email, password); - - if (!values) { - handleError(res, ERROR_MESSAGE.notFound); - return; - } - - const result = { - accessToken: values.accessToken, - refreshToken: values.refreshToken, - }; - - await redis.set(REDIS_KEY.refreshToken(values.id), values.refreshToken); - - handleSuccess( - res, - { - ...SUCCESS_MESSAGE.loginOk, - result, - }, - 200, - ); - }; - const register = async ( req: FastifyRequest<{ Body: { email: string; password: string; name: string; nickname: string; birthdate: string }; @@ -128,20 +94,15 @@ function authController() { const logout = async (req: FastifyRequest, res: FastifyReply) => { const id = req.user?.id; - const refreshToken = req.cookies.refresh_token; + const refreshToken = req.headers['refresh-token'] as string; - if (!id || !refreshToken) { + if (!id || !refreshToken || refreshToken === 'null' || refreshToken === '') { handleError(res, ERROR_MESSAGE.unauthorized); return; } try { await redis.del(REDIS_KEY.refreshToken(id)); - - res.clearCookie('refresh_token', { - path: '/', - }); - handleSuccess(res, SUCCESS_MESSAGE.logoutOk, 205); } catch (error) { handleError(res, ERROR_MESSAGE.badRequest, error); @@ -150,7 +111,7 @@ function authController() { const refresh = async (req: FastifyRequest, res: FastifyReply) => { const id = req.user?.id; - const refreshToken = req.cookies.refresh_token; + const refreshToken = req.headers['refresh-token'] as string; if (!refreshToken || !id) { handleError(res, ERROR_MESSAGE.unauthorized); @@ -167,20 +128,13 @@ function authController() { const result = await authService.refresh(refreshToken, redisRefreshToken); - res.setCookie('refresh_token', result.refreshToken, { - sameSite: 'lax', - httpOnly: true, - secure: false, - path: '/', - expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7), - }); - await redis.set(REDIS_KEY.refreshToken(id), result.refreshToken); handleSuccess(res, { ...SUCCESS_MESSAGE.refreshToken, result: { accessToken: result.accessToken, + refreshToken: result.refreshToken, }, }); } catch (error) { @@ -188,44 +142,6 @@ function authController() { } }; - const refreshMobile = async (req: FastifyRequest, res: FastifyReply) => { - const id = req.user?.id; - const refreshToken = req.cookies.refresh_token; - - if (!refreshToken || !id) { - handleError(res, ERROR_MESSAGE.unauthorized); - return; - } - - try { - const redisRefreshToken = await redis.get(REDIS_KEY.refreshToken(id)); - - if (!redisRefreshToken) { - handleError(res, ERROR_MESSAGE.unauthorized); - return; - } - - const result = await authService.refresh(refreshToken, redisRefreshToken); - - res.setCookie('refresh_token', result.refreshToken, { - sameSite: 'lax', - httpOnly: true, - secure: false, - path: '/', - expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7), - }); - - await redis.set(REDIS_KEY.refreshToken(id), result.refreshToken); - - handleSuccess(res, { - ...SUCCESS_MESSAGE.refreshToken, - result, - }); - } catch (error) { - handleError(res, ERROR_MESSAGE.unauthorized, error); - } - }; - const verifyToken = async (req: FastifyRequest, res: FastifyReply) => { const accessToken = req.headers.authorization; if (!accessToken) { @@ -254,15 +170,20 @@ function authController() { }; const loginStatusCheck = async (req: FastifyRequest, res: FastifyReply) => { - const id = req.user?.id; - const refreshToken = req.cookies.refresh_token; + const refreshToken = req.headers['refresh-token'] as string; - if (!id || !refreshToken) { + if (!refreshToken || refreshToken === 'null' || refreshToken === '') { handleSuccess(res, SUCCESS_MESSAGE.loginStatusDisabled, 200); return; } - handleSuccess(res, SUCCESS_MESSAGE.loginStatusOK, 200); + try { + shortVerifyRefreshToken(refreshToken); + handleSuccess(res, SUCCESS_MESSAGE.loginStatusOK, 200); + } catch (error) { + handleSuccess(res, SUCCESS_MESSAGE.loginStatusDisabled, 200); + return; + } }; return { @@ -272,8 +193,6 @@ function authController() { refresh, verifyToken, healthCheck, - mobileLogin, - refreshMobile, loginStatusCheck, }; } diff --git a/src/backend/auth-server/src/routes/auth/index.ts b/src/backend/auth-server/src/routes/auth/index.ts index c385703a..8a3880f1 100644 --- a/src/backend/auth-server/src/routes/auth/index.ts +++ b/src/backend/auth-server/src/routes/auth/index.ts @@ -3,8 +3,6 @@ import { ZodTypeProvider } from 'fastify-type-provider-zod'; import { healthCheckSchema, logoutSchema, - mobileSignInSchema, - refreshTokenMobileSchema, refreshTokenSchema, registerSchema, signInSchema, @@ -18,6 +16,7 @@ const authRoute = async (app: FastifyInstance) => { app.withTypeProvider().route({ method: 'GET', url: '/status-check', + preHandler: [verifySignIn], schema: loginStatusCheckSchema, handler: authController.loginStatusCheck, }); @@ -29,13 +28,6 @@ const authRoute = async (app: FastifyInstance) => { handler: authController.login, }); - app.withTypeProvider().route({ - method: 'POST', - url: '/mobile-login', - schema: mobileSignInSchema, - handler: authController.mobileLogin, - }); - app.withTypeProvider().route({ method: 'POST', url: '/register', @@ -59,13 +51,6 @@ const authRoute = async (app: FastifyInstance) => { handler: authController.refresh, }); - app.withTypeProvider().route({ - method: 'POST', - url: '/refresh-mobile', - schema: refreshTokenMobileSchema, - handler: authController.refreshMobile, - }); - app.withTypeProvider().route({ method: 'GET', url: '/verify-token', diff --git a/src/backend/auth-server/src/schema/authSchema.ts b/src/backend/auth-server/src/schema/authSchema.ts index ed3ae8cc..0cb3a713 100644 --- a/src/backend/auth-server/src/schema/authSchema.ts +++ b/src/backend/auth-server/src/schema/authSchema.ts @@ -8,25 +8,6 @@ const signInSchema = { email: z.string().email(), password: z.string(), }), - response: { - 200: z.object({ - code: z.string().default('AUTH100'), - message: z.string().default('Login Ok!'), - result: z.object({ - accessToken: z.string(), - }), - }), - 400: commonResponseSchemaOmitResult, - }, -}; - -const mobileSignInSchema = { - tags: ['auth'], - description: '모바일 로그인 합니다.', - body: z.object({ - email: z.string().email(), - password: z.string(), - }), response: { 200: z.object({ code: z.string().default('AUTH100'), @@ -81,27 +62,9 @@ const registerSchema = { const refreshTokenSchema = { tags: ['auth'], - security: [{ bearerAuth: [] }], - response: { - 201: z.object({ - code: z.string().default('AUTH102'), - message: z.string().default('refresh success'), - result: z.object({ - accessToken: z.string(), - }), - }), - 400: commonResponseSchemaOmitResult, - }, - description: ` - 리프레시 토큰은 쿠키('refresh_token')로 자동 처리됩니다. - Swagger UI에서 테스트하려면 브라우저 쿠키가 있어야 합니다. - 1. 먼저 로그인하여 쿠키 설정 - 2. 이 엔드포인트 호출하여 새 액세스 토큰 발급 -`, -}; - -const refreshTokenMobileSchema = { - tags: ['auth'], + headers: z.object({ + 'refresh-token': z.string(), + }), security: [{ bearerAuth: [] }], response: { 201: z.object({ @@ -125,6 +88,9 @@ const refreshTokenMobileSchema = { const logoutSchema = { tags: ['auth'], description: '로그아웃 합니다.', + headers: z.object({ + 'refresh-token': z.string(), + }), security: [{ bearerAuth: [] }], response: { 205: z.object({ @@ -195,10 +161,14 @@ const healthCheckSchema = { const loginStatusCheckSchema = { tags: ['auth'], description: '로그인 상태를 확인 합니다.', + security: [{ bearerAuth: [] }], response: { 200: z.object({ code: z.string().default('AUTH109'), message: z.string().default('login status check success!'), + result: z.object({ + status: z.boolean(), + }), }), 401: commonResponseSchema, }, @@ -207,11 +177,9 @@ const loginStatusCheckSchema = { export { logoutSchema, refreshTokenSchema, - refreshTokenMobileSchema, verifyTokenSchema, registerSchema, signInSchema, - mobileSignInSchema, verifyEmailSchema, tokenDecodeSchema, healthCheckSchema,