File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change 1+ 'use client' ;
2+
13import Sidebar from '@/components/common/Sidebar' ;
4+ import { useAuthGuard } from '@/hooks/useAuthGuard' ;
25
36import '@uiw/react-md-editor/markdown-editor.css' ;
47import '@uiw/react-markdown-preview/markdown.css' ;
@@ -8,6 +11,13 @@ export default function SidebarLayout({
811} : {
912 children : React . ReactNode ;
1013} ) {
14+ const { loading, isAuthed } = useAuthGuard ( { redirectTo : '/login' } ) ;
15+
16+ if ( loading ) return < div > 로딩중...</ div > ;
17+ if ( ! isAuthed ) {
18+ return null ;
19+ }
20+
1121 return (
1222 < div className = "flex" >
1323 < Sidebar />
Original file line number Diff line number Diff line change @@ -22,12 +22,19 @@ const LoginForm = ({ handleOpenModal }: LoginFormProps) => {
2222
2323 const router = useRouter ( ) ;
2424
25+ // 쿠키 설정 헬퍼 함수
26+ const setLoginCookie = ( ) => {
27+ // 7일간 유지되는 쿠키 설정
28+ document . cookie = 'isLoggedIn=true; path=/; max-age=' + 60 * 60 * 24 * 7 ;
29+ } ;
30+
2531 const handleGithubLogin = async ( ) => {
2632 if ( isLoading ) return ;
2733 setIsLoading ( true ) ;
2834 setError ( '' ) ;
2935 try {
3036 await signupWithGithub ( ) ;
37+ setLoginCookie ( ) ; // 쿠키 설정
3138 router . push ( '/' ) ;
3239 } catch ( err : unknown ) {
3340 setError ( 'Github 로그인에 실패했습니다.' ) ;
@@ -58,6 +65,7 @@ const LoginForm = ({ handleOpenModal }: LoginFormProps) => {
5865 password
5966 ) ;
6067 // console.log('로그인 성공!', userCredential.user);
68+ setLoginCookie ( ) ; // 쿠키 설정
6169 router . push ( '/' ) ;
6270 } catch ( err ) {
6371 // console.error('로그인 에러:', err);
Original file line number Diff line number Diff line change @@ -26,8 +26,10 @@ const Sidebar = () => {
2626 const handleLogout = async ( ) : Promise < void > => {
2727 try {
2828 await signOut ( auth ) ;
29+ document . cookie =
30+ 'isLoggedIn=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT' ;
31+ alert ( '로그아웃 되었습니다.' ) ;
2932 router . replace ( '/landing' ) ;
30- router . refresh ( ) ; // 서버 컴포넌트/세션 UI 갱신
3133 } catch ( err ) {
3234 console . error ( '로그아웃 실패:' , err ) ;
3335 alert ( '로그아웃에 실패했습니다.' ) ;
Original file line number Diff line number Diff line change @@ -15,7 +15,6 @@ const Markdown = dynamic(
1515const PostDetail = ( { tilId } : { tilId : string } ) => {
1616 const router = useRouter ( ) ;
1717 const [ data , setData ] = useState < Til | null > ( null ) ;
18- const [ loading , setLoading ] = useState ( true ) ;
1918
2019 useEffect ( ( ) => {
2120 const unsub = auth . onAuthStateChanged ( async ( user ) => {
@@ -26,13 +25,11 @@ const PostDetail = ({ tilId }: { tilId: string }) => {
2625
2726 const post = await fetchMyTil ( user . uid , tilId ) ;
2827 setData ( post ) ;
29- setLoading ( false ) ;
3028 } ) ;
3129
3230 return ( ) => unsub ( ) ;
3331 } , [ tilId , router ] ) ;
3432
35- if ( loading ) return < div className = "min-h-screen p-6" > 로딩중...</ div > ;
3633 if ( ! data ) return < div className = "min-h-screen p-6" > 글이 없습니다.</ div > ;
3734
3835 return (
Original file line number Diff line number Diff line change 1+ 'use client' ;
2+
3+ import { useEffect , useState } from 'react' ;
4+ import { onAuthStateChanged , type User } from 'firebase/auth' ;
5+ import { useRouter } from 'next/navigation' ;
6+ import { auth } from '@/lib/firebase' ;
7+
8+ type UseAuthGuardOptions = {
9+ /** 로그인 안 됐을 때 보낼 경로 */
10+ redirectTo ?: string ;
11+ } ;
12+
13+ type UseAuthGuardResult = {
14+ user : User | null ;
15+ loading : boolean ;
16+ isAuthed : boolean ;
17+ } ;
18+
19+ export function useAuthGuard (
20+ options : UseAuthGuardOptions = { }
21+ ) : UseAuthGuardResult {
22+ const { redirectTo = '/login' } = options ;
23+
24+ const router = useRouter ( ) ;
25+ const [ user , setUser ] = useState < User | null > ( null ) ;
26+ const [ loading , setLoading ] = useState ( true ) ;
27+
28+ useEffect ( ( ) => {
29+ const unsub = onAuthStateChanged ( auth , ( u ) => {
30+ if ( ! u ) {
31+ setUser ( null ) ;
32+ setLoading ( true ) ;
33+ router . replace ( redirectTo ) ;
34+ return ;
35+ }
36+ setUser ( u ) ;
37+ setLoading ( false ) ;
38+ } ) ;
39+
40+ return ( ) => unsub ( ) ;
41+ } , [ router , redirectTo ] ) ;
42+
43+ return { user, loading, isAuthed : ! ! user } ;
44+ }
Original file line number Diff line number Diff line change 1+ import { NextResponse } from 'next/server' ;
2+ import type { NextRequest } from 'next/server' ;
3+
4+ export function middleware ( request : NextRequest ) {
5+ const { pathname } = request . nextUrl ;
6+
7+ // 쿠키에서 isLoggedIn 확인
8+ const isLoggedIn = request . cookies . get ( 'isLoggedIn' ) ?. value === 'true' ;
9+
10+ if ( pathname === '/' ) {
11+ // 로그인이 안 된 경우에만 랜딩으로 보냄
12+ if ( ! isLoggedIn ) {
13+ return NextResponse . redirect ( new URL ( '/landing' , request . url ) ) ;
14+ }
15+ // 로그인 된 상태라면 그대로 루트('/')를 보여줌
16+ return NextResponse . next ( ) ;
17+ }
18+
19+ if ( pathname === '/landing' && isLoggedIn ) {
20+ return NextResponse . redirect ( new URL ( '/' , request . url ) ) ;
21+ }
22+
23+ return NextResponse . next ( ) ;
24+ }
25+
26+ export const config = {
27+ matcher : [ '/' , '/landing' ] ,
28+ } ;
You can’t perform that action at this time.
0 commit comments