sveltekit と supabase auth のセットアップめも

いろいろ docs で迷子になったりしたので

パッケージ

2024年1月現在、 @supabase/auth-helpers-sveltekit@supabase/ssr の2つの packages のドキュメントが生きてる
使うのは @supabase/ssr の方

ssr が新しいというのはここに書いてある↓

We generally recommend using the new @supabase/ssr package instead of auth-helpers. @supabase/ssr takes the core concepts of the Auth Helpers package and makes them available to any server framework. Check out the migration doc to learn more.

自分は auth-helpers-sveltekit のインストールに sveltekit のバージョン違いで失敗したあとこの GitHub issueを見て「あーね」ってなった

migration guide: https://supabase.com/docs/guides/auth/server-side/migrating-to-ssr-from-auth-helpers?framework=sveltekit

コード: client をつくる

ここの手順に沿って進めれば ok なんだけど
https://supabase.com/docs/guides/auth/server-side/creating-a-client
初めての sveltekit なのでちょくちょく躓いた

つまづき1: event.locals の型

結論からいうと app.d.tsinterface Locals に型を追加すれば ok

// import types from supabase
import type { Session, SupabaseClient } from "@supabase/supabase-js"

declare global {
    namespace App {
                 // ...

                 // add these
        interface Locals {
            getSession: () => Promise<Session | null>
            supabase: SupabaseClient
        }

                 // ...
    }
}

export { }

event.locals に型付けをする方法は AFAIK docs に明示的に書いてなかったけど、検索したら「 app.d.ts をいじれ」と書いてあった
で、ファイルをひらくと「https://kit.svelte.dev/docs/types#app を読んでね」とぬるっとコメントしてある

Argument of type 'Partial' is not assignable to parameter of type 'CookieSerializeOptions & { path: string; }'.

っていうエラーが handle function の setremove で出てくる

直し方はこう

export const handle: Handle = async ({ event, resolve }) => {
  event.locals.supabase = createServerClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
    cookies: {
      get: (key) => event.cookies.get(key),
      set: (key, value, options) => {
        // fix
        - event.cookies.set(key, value, { ...options, path: "/" })
        + event.cookies.set(key, value, options)
      },
      remove: (key, options) => {
        // fix
        - event.cookies.delete(key, options)
        +  event.cookies.delete(key, { ...options, path: "/" })
      },
    },
  })

ソースは Reddit のコメントという微妙なものなんだけど (しかも 1 upvote)、実際に型とあってるのでそうなんだと思う

this is happening because since SvelteKit 2, path is now a required property when setting cookies. this is how to fix it: { ...options, path: '/' }

https://www.reddit.com/r/Supabase/comments/18rkrs5/comment/kfmkouc/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button

コード: email からの URL たちを設定

招待メールとか confirm email address のメールとかも別途設定が必要。これは↓のリンク通りにやればそのままできる。

https://supabase.com/docs/guides/auth/server-side/email-based-auth-with-pkce-flow-for-ssr?framework=sveltekit

一個気になったのは、

const { error } = await supabase.auth.verifyOtp({ token_hash, type })

のところで、 type の型が VSCode に怒られることなんだけど、一方でこれを厳密に型チェックすると supabase 側で MobileOtpType EmailOtpType の中身が変更されたときメンテができなそう.. と思って放置している。エラーメッセージはこれ

Type 'string' is not assignable to type 'MobileOtpType | EmailOtpType'.

妙案があればおしえてほしい

注意

Beware when accessing the session object on the server, because it is not revalidated on every request from the client. That means the sender can tamper with unencoded data in the session object. If you need to verify the integrity of user data for server logic, call auth.getUser instead, which will query the Supabase Auth server for trusted user data.

https://supabase.com/docs/guides/auth/server-side/creating-a-client?framework=sveltekit

session = await getSession() すると Session type の object が返ってきて、 session.user で user の email とかをとってこれるんだが、これの取り扱いに注意、ということらしい。ログイン中のユーザの username を表示するくらいならそのまま使って良さそうと思っている

リンク集

どこを見ればええねんってやつ

SSR は docs > Auth の "SERVER-SIDE AUTH" のセクションをみておけばよさそう

今回参考にしたのは

あとはここも見ておくとよさそう

✄--------------- キ リ ト リ ---------------✄

今日はここまで、またあったら追記する