From 1eec8609b7f23f30423c08ecdcce9f805379c23f Mon Sep 17 00:00:00 2001 From: timepresent95 Date: Tue, 20 Aug 2024 19:44:22 +0900 Subject: [PATCH] refactor: auth API #19 --- src/mocks/handlers/auth.ts | 139 ++++++++++++++++++++----------------- src/mocks/utils/token.ts | 36 +++++----- src/utils/token.ts | 6 +- 3 files changed, 99 insertions(+), 82 deletions(-) diff --git a/src/mocks/handlers/auth.ts b/src/mocks/handlers/auth.ts index 1f2d0e4..488cd47 100644 --- a/src/mocks/handlers/auth.ts +++ b/src/mocks/handlers/auth.ts @@ -4,79 +4,94 @@ import {http, HttpResponse} from 'msw'; import {getApiUrl} from '../utils/api'; -import {RequestSignIn, RequestSignUp, ResponseToken} from '@/api/auth'; +import { + //NOTE: 로그인 실패 -> 회원 가입 로직 + // RequestSignIn, + ResponseToken, +} from '@/api/auth'; import {authApis} from '@/api/routes'; -import {createUser} from '@/mocks/fakers'; -import {createFakeJWT} from '@/mocks/utils/token'; +import {createFakeToken, setFakeToken} from '@/mocks/utils/token'; export default [ - http.post(getApiUrl(authApis.signIn), async ({request}) => { - const body = (await request.json()) as Partial; - const {OAuthProvider, AuthorizationCode} = body; - const oauthAgent = ['NATIVE', 'GOOGLE', 'NAVER', 'KAKAO', 'APPLE']; - if ( - !OAuthProvider || - !oauthAgent.includes(OAuthProvider) || - !AuthorizationCode - ) { - return new HttpResponse(null, { - status: 400, - statusText: 'Bad Request', - }); - } + http.post(getApiUrl(authApis.signUp), () => { + const accessToken = createFakeToken(); + const refreshToken = createFakeToken(true); + setFakeToken({accessToken, refreshToken}); + + const response = { + accessToken, + refreshToken, + grantType: 'Bearer', + } as ResponseToken; + + return HttpResponse.json(response, {status: 201}); + }), + http.post(getApiUrl(authApis.signIn), async () => { //NOTE: 로그인 실패 -> 회원 가입 로직 - // return HttpResponse.json( - // { - // code: 'AUTH-0001', - // message: '가입하지 않은 회원입니다. 회원가입을 진행해주세요.', - // data: { - // OAuthProvider, - // AuthorizationCode, - // email: faker.internet.email(), - // }, - // }, - // { - // status: 401, - // statusText: 'Unauthorized', + // const body = (await request.json()) as RequestSignIn; + // const {OAuthProvider, AuthorizationCode} = body; + // const userEmail = faker.internet.email(); + // const response = { + // code: 'AUTH-0001', + // message: '가입하지 않은 회원입니다. 회원가입을 진행해주세요.', + // data: { + // OAuthProvider, + // AuthorizationCode, + // email: userEmail, // }, - // ); + // }; + // return HttpResponse.json(response, { + // status: 403, + // statusText: 'Forbidden', + // }); //NOTE: 로그인 성공 로직 - return HttpResponse.json({ - accessToken: createFakeJWT(createUser(true)), - refreshToken: createFakeJWT(createUser(true), 24 * 60 * 60), + const accessToken = createFakeToken(); + const refreshToken = createFakeToken(true); + + setFakeToken({accessToken, refreshToken}); + + const response = { + accessToken, + refreshToken, grantType: 'Bearer', - } as ResponseToken); + } as ResponseToken; + + return HttpResponse.json(response, {status: 201}); }), - http.get(getApiUrl(authApis.signOut), () => { - return new HttpResponse(null, { - status: 204, - statusText: 'No Content', - }); + http.patch(getApiUrl(authApis.signOut), () => { + const accessToken = createFakeToken(); + const refreshToken = createFakeToken(true); + + setFakeToken({accessToken, refreshToken}); + + const response = { + accessToken, + refreshToken, + grantType: 'Bearer', + } as ResponseToken; + + return HttpResponse.json(response, {status: 201}); }), - http.post(getApiUrl(authApis.signUp), async ({request}) => { - const body = (await request.json()) as RequestSignUp; - if ( - !( - body.nickName && - body.OAuthProvider && - body.birth && - body.birthType && - body.email && - body.groupRole && - (body.familyCode || body.familyCode === null) - ) - ) { - return new HttpResponse(null, { - status: 400, - statusText: 'Bad Request', - }); - } - return HttpResponse.json({ - accessToken: createFakeJWT(createUser(true)), - refreshToken: createFakeJWT(createUser(true), 24 * 60 * 60), + http.patch(getApiUrl(authApis.reIssueToken), () => { + const accessToken = createFakeToken(); + const refreshToken = createFakeToken(true); + + setFakeToken({accessToken, refreshToken}); + + const response = { + accessToken, + refreshToken, grantType: 'Bearer', - } as ResponseToken); + } as ResponseToken; + + return HttpResponse.json(response, {status: 201}); + }), + http.get(getApiUrl(authApis.validateFamilyCode), () => { + return HttpResponse.json({isValidate: true}); + }), + http.patch(getApiUrl(authApis.reRegistrationAlertToken), () => { + return HttpResponse.json(); }), ]; diff --git a/src/mocks/utils/token.ts b/src/mocks/utils/token.ts index 520ff5a..0af880c 100644 --- a/src/mocks/utils/token.ts +++ b/src/mocks/utils/token.ts @@ -2,8 +2,6 @@ import {Buffer} from 'buffer'; import {faker} from '@faker-js/faker'; -import {Member} from '@/types'; - const SECRET_KEY = 'secret-key'; function base64Encode(str: string) { @@ -14,10 +12,8 @@ function base64Decode(str: string) { return Buffer.from(str, 'base64').toString('utf-8'); } -export function createFakeJWT( - payload: Member, - expiresInSeconds: number = 60 * 60, -) { +export function createFakeToken(isRefresh = false) { + const expiresInSeconds = isRefresh ? 24 * 60 * 60 : 60 * 60; const header = { alg: 'HS256', typ: 'JWT', @@ -30,7 +26,6 @@ export function createFakeJWT( iat: currentTime, exp: currentTime + expiresInSeconds, noncee: faker.string.uuid(), - ...payload, }), ); const signature = base64Encode( @@ -38,24 +33,29 @@ export function createFakeJWT( ); const token = `${encodedHeader}.${encodedPayload}.${signature}`; + return token; } -export function verifyFakeJWT(token: string) { +type FakeTokens = {accessToken: string | null; refreshToken: string | null}; + +let myFakeTokens: FakeTokens = { + accessToken: null, + refreshToken: null, +}; + +export function setFakeToken(tokens: Partial) { + myFakeTokens = {...myFakeTokens, ...tokens}; +} + +export function verifyFakeToken(token: string) { try { const parts = token.split('.'); if (parts.length !== 3) { return false; } - const [encodedHeader, encodedPayload, signature] = parts; - const validSignature = base64Encode( - `${encodedHeader}.${encodedPayload}.${SECRET_KEY}`, - ); - - if (signature !== validSignature) { - return false; - } + const [, encodedPayload] = parts; const payload = JSON.parse(base64Decode(encodedPayload)); @@ -64,7 +64,9 @@ export function verifyFakeJWT(token: string) { return false; // 토큰이 만료됨 } - return true; + return ( + token === myFakeTokens.accessToken || token === myFakeTokens.refreshToken + ); } catch (error) { return false; } diff --git a/src/utils/token.ts b/src/utils/token.ts index a00b0ca..6bb7871 100644 --- a/src/utils/token.ts +++ b/src/utils/token.ts @@ -1,8 +1,8 @@ -import {Member} from '@/types'; +import {UserInfo} from '@/types'; //NOTE: 유저 정보를 토큰에서 얻기 위한 함수 //FIXME: BE에서 전달해준 payload가 정해지면 수정해야 함 -export function getUserFromToken(token: string): Member | null { +export function getUserFromToken(token: string): UserInfo | null { try { const parts = token.split('.'); if (parts.length !== 3) { @@ -15,7 +15,7 @@ export function getUserFromToken(token: string): Member | null { ); const payload = JSON.parse(decodedPayload); - return payload as Member; + return payload as UserInfo; } catch (error) { return null; }