Supabase SSR 세션

장석원·2026년 10월 9일

getUser vs getSession

한줄로 설명하자면, 말 그대로 getSession은 쿠키에 저장된 값을 그대로 꺼내 읽고,
getUser는 그 토큰을 Supabase Auth 서버에 보내 진짜인지 확인받는다.
쿠키는 클라이언트가 마음대로 조작할 수 있기 때문에, 서버에서 권한을 판단할 때는 검증을 거친 쪽을 사용해야한다.

서버 왕복이 있는 쪽.
당연히 getUser이다.
같은 토큰을 Auth 서버 /auth/v1/user로 전송, 네트워크는 매번 요청, 검증은 서버가 서명과 유저 존재 여부를 확인

getSession은 쿠키에 저장된 세션 JSON, 네트워크는 없음, 단 만료된 토큰이면 refresh 요청을 보낸다. 검증은 만료 시각 정도만 확인하고 서명은 확인하지 않는다.

getSession은 기본적으로 네트워크를 쓰지 않는다.
예외는 토큰이 만료되었을때 refresh가 일어나는 경우인데, 이때는 갱신 요청이 나가고 새 쿠키를 써야하는 상황이 생긴다.

getUser 가 더 안전한 이유

당연히 서버와 통신을 해서 검증하니 안전하겠다
getSession 같은 경우는 쿠키에 있으니까 맞겠지 라는 전제로 동작하고,
getUser는 해당 토큰이 우리 서버가 발급한 것이 맞는지 Auth 서버에 물어본다.

getUser와 getSession은 둘 다 "로그인 여부"를 알려주는 것 같은데 왜 다른 함수로 나뉘어 있나, 그리고 server Component가 쿠키를 못 쓰는 이유는 뭔지.

  • 쿠키값 확인안하고 위조 공격 할 수 있다.
  • 오탐: 이미 무효인데 로그인으로 판정

Server Component는 왜 쿠키를 쓸 수 없는지

쿠키를 쓰는 것은 결국 HTTP 응답 헤더에 Set-Cookie를 넣는 일이다.
그런데 헤더는 응답 본문보다 먼저, 한 번만 보낼 수 있다.

  • App Router는 Server Component를 스트리밍으로 렌더링 한다.
    layout과 Suspense 바깥 부분이 먼저 전송되고, 안쪽 컴포넌트는 그 뒤에 렌더링된다.

try/catch 써야하는 이유

setAll은 Supabase 클라이언트가 토큰을 갱신했을 때만 호출된다.
에러를 그대로 던지면 평소에는 문제 없다가, 토큰이 만료 직전인 요청에서만 페이지가 에러 바운더리나 500으로 떨어진다. 재션이 잘 안되는 간헐적 버그 ... 예전에 내가 겪었다.. axios 썼을때 refresh 토큰 갱신이였던 것 같은데

middleware 가 이미 갱신을 처리하고 있기 때문. middleware 없이 삼키기만 하면 갱신된 토큰이 버려지게 된다.
Suapbase 는 refresh token을 한 번 쓰면 새 톸느으로 교체하는 방식이라, 새 토큰이 저장되지 않으면 당므 요청이 이미 사용된 refresh token을 다시 보내게되고, 그 결과 갑자기 로그아웃되는 증상이 생길 수 있다.

0개의 댓글