DEV Community

Beaver Bridge
Beaver Bridge

Posted on

SvelteKit + supabase 세션 만료 처리

supabase 라이브러리에서는 https://supabase.com/docs/reference/javascript/auth-exchangecodeforsession 이런 식으로 auth가 변경됐다라는 것을 받을 수만 있다.
그래서인지 탭을 계속 열어놓은 상태거나 심지어 pc를 종료하고 며칠 후에 켜도 자동으로 세션을 업데이트 해버린다.

다행히 Svelte를 좀 아는 분의 도움을 받아서 브라우저가 종료됐을 때는 처리가 됐으나 여전히 탭을 계속 열어놓은 상태에서는 세션이 유지된다. 보통의 사이트처럼 세션이 만료 됐습니다. 다시 로그인하세요 같은 걸 띄워야 하는데...

이리저리 찾아봐도 딱히 방법이 없는 것 같아서 원시적인 방법으로 처리하기로 했다.

// app.d.ts
declare global {
  namespace App {
    interface Locals {
      sb: SupabaseClient;
      getSession(): Promise<Session | null>;
      user_last_activity_at: Date | null;
      ...
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
// hooks.server.js
import { DateTime } from "luxon";

export const handle = async ({ event, resolve }) => {
  event.locals.user_last_activity_at = DateTime.now().toISO();
  ...
}
Enter fullscreen mode Exit fullscreen mode

hooks.server.js 는 화면이 호출될 때마다 호출이 되기 때문에 여기서 마지막 활동 시간을 저장한다.

// +layout.server.js
return {
  user_last_activity_at: locals.user_last_activity_at,
  ...
}
Enter fullscreen mode Exit fullscreen mode
// +layout.js
return {
  user_last_activity_at: data.user_last_activity_at,
  ...
}
Enter fullscreen mode Exit fullscreen mode
// +layout.svelte
<script>
  import { beforeUpdate } from "svelte";
  import { goto } from "$app/navigation";
  import { DateTime } from "luxon";

  export let data;
  $: ({ supabase, session } = data);

  let wasCallGoToLogin = false; // beforeUpdate가 여러 번 호출돼서 회피용

  beforeUpdate(async () => {
    const userLastActivityMinute = DateTime.fromISO(data.user_last_activity_at).diffNow("minutes").minutes;
    // 마지막 활동이 30분 이상 지났을 경우 로그아웃 시킨다.
    if (!wasCallGoToLogin && $page.route.id != "/login" && userLastActivityMinute < -30) {
      alert("로그인이 만료되었습니다. 다시 로그인해주세요.");
      wasCallGoToLogin = true;
      await supabase.auth.signOut();
      goto("/login");
    }
  });
</script>
Enter fullscreen mode Exit fullscreen mode

SvelteKit은 기본 설정이 data-sveltekit-preload-data="hover"라서 링크에 마우스 커서만 올려도 백그라운드에서 호출을 해버린다. 그래서 다른 걸 하기 전에 세션 만료 처리를 할 수 있다.

다만 여전히 문제는 있는데, 작성에 30분 이상 걸리면 저장하기 전에 로그인이 종료된다. 사용자들이 잘 알아서 써주겠지...

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)