Skip to content

Commit

Permalink
Login, Logout, 로그인유지 (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
aaaz425 authored Aug 2, 2024
2 parents 1fc869e + b93542f commit c559c57
Show file tree
Hide file tree
Showing 18 changed files with 102 additions and 36 deletions.
10 changes: 0 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@
"eslint-plugin-unused-imports": "^3.2.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"js-cookie": "^3.0.5",
"kakao.maps.d.ts": "^0.1.40",
"msw": "^2.3.0",
"postcss": "^8",
Expand Down
Binary file added public/image/user1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/api/sign/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,8 @@ export const updatePassword = async (
const { data } = await fetcher.patch(END_POINT.USER.UPDATEPW, userData);
return data;
};

export const userCheck = async () => {
const { data } = await fetcher.get(`${END_POINT.USER.USERINFO}`);
return data;
};
5 changes: 0 additions & 5 deletions src/app/(header)/login/_component/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
'use client';
import Cookies from 'js-cookie';
import { useRouter } from 'next/navigation';
import React, { useState } from 'react';
import { useForm } from 'react-hook-form';
Expand Down Expand Up @@ -35,10 +34,6 @@ export default function LoginForm() {
setErrorMessage(result.message);
} else {
setErrorMessage('');
Cookies.set('accessToken', result.accessToken, {
secure: true,
expires: new Date(Date.now() + 60 * 60 * 1000),
});
router.push('/');
}
setIsLoading(false);
Expand Down
4 changes: 1 addition & 3 deletions src/app/(header)/mypage/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@ import React from 'react';
import ProfileHeader from './_component/ProfileHeader';
import ProfileReview from './_component/ProfileReview';

function page() {
export default function Page() {
return (
<>
<ProfileHeader />
<ProfileReview />
</>
);
}

export default page;
5 changes: 5 additions & 0 deletions src/app/(header)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { QueryClient } from '@tanstack/react-query';
import HomeReview from '@/app/_components/HomeReview';
import prefetchAuthSSR from '@/utils/prefetchAuthSSR';
import HomeFAB from '../_components/HomeFAB';
import HomeRecommend from '../_components/HomeRecommend';

export default function Home() {
// Memo: top button 추가할지 기획에게 문의하기

const queryClient = new QueryClient();
prefetchAuthSSR(queryClient);
return (
<main className="flex flex-col gap-32 p-16">
<HomeRecommend />
Expand Down
3 changes: 0 additions & 3 deletions src/app/(header)/write/page.tsx

This file was deleted.

24 changes: 23 additions & 1 deletion src/app/(no_header)/my-setting/_component/LogOutModal.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useRouter } from 'next/router';
import React from 'react';
import Button from '@/components/Button/Button';

Expand All @@ -6,6 +7,22 @@ type LogOutModalProps = {
};

export default function LogOutModal({ closeHandler }: LogOutModalProps) {
const router = useRouter();
const onLogoutHandler = async () => {
const result = await (
await fetch('/api/auth/logout', {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8',
},
})
).json();
if (result.status === 200) {
router.push('/');
}
console.log('result = ', result);
};

return (
<div className="w-full h-full absolute top-0 left-0 flex justify-center items-center">
<div className="relative w-3/4 h-44 z-modal bg-white rounded-lg flex flex-col justify-center items-center">
Expand All @@ -17,7 +34,12 @@ export default function LogOutModal({ closeHandler }: LogOutModalProps) {
variant="secondary"
text="취소"
/>
<Button size="s" variant="primary" text="로그아웃" />
<Button
onClick={onLogoutHandler}
size="s"
variant="primary"
text="로그아웃"
/>
</div>
</div>
</div>
Expand Down
15 changes: 14 additions & 1 deletion src/app/_components/HomeRecommend.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
'use client';

import { QueryClient, useQuery } from '@tanstack/react-query';
import { userCheck } from '@/api/sign';
import prefetchAuthSSR from '@/utils/prefetchAuthSSR';
import RecommendedCafeCarousel from './recommend/RecommendedCafeCarousel';

export default function HomeRecommend() {
const queryClient = new QueryClient();
prefetchAuthSSR(queryClient);
const { data } = useQuery({
queryKey: ['Me'],
queryFn: userCheck,
});
return (
<section className="flex flex-col gap-16">
<h2 className="text-18 font-bold">유저1 님이 좋아할 카페</h2>
<h2 className="text-18 font-bold">
{data?.data.nickName} 님이 좋아할 카페
</h2>
<RecommendedCafeCarousel />
</section>
);
Expand Down
1 change: 0 additions & 1 deletion src/components/SideNavBar/SideNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ type SideNavBarProps = {

export default function SideNavBar({ isOpen, closeHandler }: SideNavBarProps) {
useBlockScrollY({ isBlock: isOpen });

return (
<>
{isOpen && <Dim closeHandler={closeHandler} />}
Expand Down
19 changes: 17 additions & 2 deletions src/components/SideNavBar/SideNavBarHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,34 @@
'use client';

import { useQueryClient } from '@tanstack/react-query';
import Button from '../Button/Button';
import UserImage from '../UserImage';

type SideNavBarHeaderProps = {
closeHandler: () => void;
};

type UserData = {
data: {
email: string;
pw: string;
profileImg: string;
nickName: string;
};
};

export default function SideNavBarHeader({
closeHandler,
}: SideNavBarHeaderProps) {
// Todo: 유저 정보 저장 로직에 따라 재작업 필요
const queryClient = useQueryClient();
const data = queryClient.getQueryData<UserData>(['Me']);
console.log('data = ', data);
return (
<div className="flex justify-between items-center">
<div className="flex gap-8">
<UserImage src="/image/test_thumbnail.png" />
<span className="text-14 font-bold">유저1</span>
<UserImage src={`/image${data?.data.profileImg}.png`} />
<span className="text-14 font-bold">{data?.data.nickName}</span>
</div>
<Button
variant="secondary"
Expand Down
1 change: 1 addition & 0 deletions src/constants/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const END_POINT = {
SIGNIN: 'user/sign-in',
SIGNUP: 'api/user',
UPDATEPW: 'api/user/password',
USERINFO: 'user/user-info',
},
REVIEW: {
LIST: '/review',
Expand Down
5 changes: 3 additions & 2 deletions src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
export async function middleware(request: NextRequest) {
const accessToken = request.cookies.get('accessToken')?.value;

if (accessToken) {
Expand All @@ -10,6 +10,7 @@ export function middleware(request: NextRequest) {
}
} else {
// accessToken이 없고 로그인 페이지가 아닌 다른 페이지로 접근하려는 경우

if (!request.nextUrl.pathname.startsWith('/login')) {
return Response.redirect(new URL('/protect', request.url));
}
Expand All @@ -18,5 +19,5 @@ export function middleware(request: NextRequest) {

// 보안처리 페이지
export const config = {
matcher: ['/write', '/login'],
matcher: ['/review/write', '/login', '/mypage', '/my-setting'],
};
15 changes: 15 additions & 0 deletions src/mocks/browserHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,21 @@ export const browserHandlers = [
});
}),

http.get(END_POINT.USER.USERINFO, async ({ request }) => {
console.log('user-info request = ', request);

return HttpResponse.json({
status: SUCCESS_CODE.OK,
message: '유저 정보 조회 성공',
data: {
email: '[email protected]',
pw: 'qwer1234!',
profileImg: '/user1',
nickName: 'yunha',
},
});
}),

// Memo: 리뷰 좋아요 상태 변경
http.patch<never, ReviewLikeReqType>(
END_POINT.REVIEW.LIKE,
Expand Down
4 changes: 4 additions & 0 deletions src/pages/api/auth/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export default async function login(req: NextApiRequest, res: NextApiResponse) {
} else {
// 토큰 만들기
const accessToken = await sign(email);
res.setHeader(
'Set-Cookie',
`accessToken=${accessToken}; HttpOnly; Max-Age=3600; Path=/;`
);
res.status(200).json({ message: '로그인 성공', email, accessToken });
}
break;
Expand Down
14 changes: 7 additions & 7 deletions src/pages/api/auth/logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ export default async function name(req: NextApiRequest, res: NextApiResponse) {
switch (req.method) {
case 'POST':
try {
const { refreshToken } = req.cookies;
console.log('refreshToken = ', refreshToken);
const { accessToken } = req.cookies;
console.log('refreshToken = ', accessToken);
// 만료 시간을 현재 시간보다 빠르게 해서 만료되도록 하여 쿠키 삭제
// HttpOnly라 브라우저에서 임의로 쿠키 조작 불가 -> 서버에서 설정
res.setHeader(
'Set-Cookie',
`refreshToken=; Path=/; Expires=${new Date(
Date.now() - 1
).toUTCString()}; HttpOnly`
`accessToken=; HttpOnly; Max-Age=0; Path=/;`
);
if (refreshToken) {
return res.status(200).json({ message: '로그아웃 완료!' });
if (accessToken) {
return res
.status(200)
.json({ status: 200, message: '로그아웃 완료!' });
}
return res.send('이미 로그아웃 되었습니다.');
} catch (error) {
Expand Down
7 changes: 7 additions & 0 deletions src/utils/prefetchAuthSSR.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// src/utils/prefetchAuthSSR.ts
import { QueryClient } from '@tanstack/react-query';
import { userCheck } from '@/api/sign';

export default async function prefetchAuthSSR(queryClient: QueryClient) {
await queryClient.prefetchQuery({ queryKey: ['Me'], queryFn: userCheck });
}

0 comments on commit c559c57

Please sign in to comment.