[TIL #64 ] 비회원으로 둘러보기 미들웨어 처리

차슈·2024년 8월 7일
0

TIL

목록 보기
64/70
post-thumbnail

비회원으로 둘러보기 기능을 추가해야해서 미들웨어를 건들였다!

초기의 미들웨어

import { createServerClient } from '@supabase/ssr'
import { NextResponse, type NextRequest } from 'next/server'

export async function updateSession(request: NextRequest) {
  let supabaseResponse = NextResponse.next({
    request,
  })

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return request.cookies.getAll()
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => request.cookies.set(name, value))
          supabaseResponse = NextResponse.next({
            request,
          })
          cookiesToSet.forEach(({ name, value, options }) =>
            supabaseResponse.cookies.set(name, value, options)
          )
        },
      },
    }
  )

  // IMPORTANT: Avoid writing any logic between createServerClient and
  // supabase.auth.getUser(). A simple mistake could make it very hard to debug
  // issues with users being randomly logged out.

  const {
    data: { user },
  } = await supabase.auth.getUser()

  if (
    !user &&
    !request.nextUrl.pathname.startsWith('/login') &&
    !request.nextUrl.pathname.startsWith('/auth')
  ) {
    // no user, potentially respond by redirecting the user to the login page
    const url = request.nextUrl.clone()
    url.pathname = '/login'
    return NextResponse.redirect(url)
  }

  // IMPORTANT: You *must* return the supabaseResponse object as it is. If you're
  // creating a new response object with NextResponse.next() make sure to:
  // 1. Pass the request in it, like so:
  //    const myNewResponse = NextResponse.next({ request })
  // 2. Copy over the cookies, like so:
  //    myNewResponse.cookies.setAll(supabaseResponse.cookies.getAll())
  // 3. Change the myNewResponse object to fit your needs, but avoid changing
  //    the cookies!
  // 4. Finally:
  //    return myNewResponse
  // If this is not done, you may be causing the browser and server to go out
  // of sync and terminate the user's session prematurely!

  return supabaseResponse
}

슈퍼베이스 ssr 공식문서 에 나오는 미들웨어를 통해 관리하고 있었는데,

필요에 의해 비회원으로 둘러보기 기능을 만들어서 수정했다.

일단, layout이 변경되는 경우가 있어서 쿠키를 무조건 건들여야하는 상황이라,

const guestCookie = request.cookies.get('guest');
const isGuest = guestCookie?.value === 'true';

이렇게 비회원으로 들어가면 Guest = true가 되게 쿠키를 추가해줬다.

  const publicRoutes = ['/sign-up', '/log-in']; // 누구나 접근 가능 
  const protectedRoutes = ['/my-page']; // 비회원 접근 불가능 

그리고 user와 user가 없을 시 (비회원)에도 누구나 접근 가능한 루트와 user가 없을때는 접근 불가능한 루트를 설정해 주었다.

만약, 비회원이 불가능한 경로인 mypage에 접근하려고 하면, 무조건 로그인 페이지로 리다이렉트 하게 했다.

  // 비회원이 불가능 경로에 접근하려고 할 때 리다이렉트
  if (!user && !isGuest && protectedRoutes.includes(request.nextUrl.pathname)) {
    url.pathname = '/log-in'; 
    return NextResponse.redirect(url);
  }

로그인이 성공했다라는건 user가 있다 라는 뜻이기 때문에 비회원과 관련된 쿠키는 삭제 시켜줬다. 그래야 온전히 user로써 들어갈 페이지를 들어갈 수 있기 때문!

  // 로그인한 사용자에게는 모든 페이지 접근 허용
  if (user) {
    // 로그인 성공 시 비회원 쿠키 삭제
    supabaseResponse.cookies.delete('guest');
    return supabaseResponse;
}

생각보다 오래걸렸다. 일단, 쿠키를 건드는건 불가피했기에 오래걸릴거라는 생각은 했다.

아, 그리고 이 비회원 덕분에 로그인 코드도 손봐서 tanstack query로 로그인 하게 바꿔놨다. 처음에 자꾸 안되어서 tanstack quer가 작동을 안하나보다 하고 다 바꿔놨다..
아무튼 해결~~

  • 유저테스트르 받고 있다. 사실 모든게 완벽한건 아닌데, 그냥 일단 유저테스트를 먼저 받는게 나을거같다는 팀원들 의견으로 유저테스트를 진행중인데,
    vercel이 터짐,,,,,,,,이미지가 1000개인데 유저테스트에서 생각보다 몰리면서 vercel이 터져서 프로필 이미지가 안나오는 이슈 발생. 아마 이미지 중에서 가장 마지막에 작업해서 나머지는 다 로딩되고 일단 프로필만 터졌는데, 이건 vercel 결제하면 어차피 해결될 일이지만, 402 에러나는거 보면 맘이 아파서 배포 링크 못보는중임,,,,,,, 그치만 결제만 하면 해결될 일이라는거에 감사해야하는중~ 아무튼 다들 너무 자세하고 세세하게 피드백을 주셔서 오히려 생각지 못한 부분도 많이 나왔던거같아서 '이래서 유저테스트 하는구나' 를 깨달았다.

0개의 댓글