如何实现非邮箱用户ID认证?求Supabase与Dexie-Cloud集成示例
解决方案
关于Dexie-Cloud自定义用户ID的问题
你完全可以扩展Dexie-Cloud的默认认证逻辑,不用邮箱作为userId,改用UUID或其他自定义值,同时将邮箱存储在用户的附加数据字段中:
- 初始化DexieCloud时,通过
auth配置项自定义用户ID的来源,比如从认证提供者的JWT Claims中提取UUID; - 将邮箱等敏感信息存入
userData字段,该字段默认不会被暴露给其他用户(除非你显式配置权限)。
示例配置片段:
import { Dexie } from 'dexie'; import { dexieCloud } from 'dexie-cloud-addon'; const db = new Dexie('MyDB', { addons: [dexieCloud] }); db.configure({ databaseUrl: 'https://your-dexie-cloud-url.com', auth: { // 自定义从JWT中提取userId(比如用UUID) userIdFromJwt: (jwt) => jwt.sub, // 假设sub是UUID格式的用户ID // 将邮箱存入userData userDataFromJwt: (jwt) => ({ email: jwt.email }) } });
Supabase与Dexie-Cloud集成的SvelteKit示例
以下是完整的SvelteKit集成步骤,核心逻辑是用Supabase的认证会话来获取Dexie-Cloud的访问权限:
1. 安装依赖
npm install dexie dexie-cloud-addon supabase-js @supabase/auth-helpers-sveltekit
2. 配置Supabase客户端(src/lib/supabaseClient.js)
import { createClient } from '@supabase/auth-helpers-sveltekit'; import { env } from '$env/dynamic/public'; export const supabase = createClient(env.PUBLIC_SUPABASE_URL, env.PUBLIC_SUPABASE_ANON_KEY);
3. 配置Dexie-Cloud数据库(src/lib/db.js)
import { Dexie } from 'dexie'; import { dexieCloud } from 'dexie-cloud-addon'; import { supabase } from './supabaseClient'; const db = new Dexie('MySupabaseDexieDB', { addons: [dexieCloud] }); // 定义你的数据库表结构 db.version(1).stores({ tasks: 'id, title, done, userId' }); db.configure({ databaseUrl: 'https://your-dexie-cloud-url.com', auth: { // 使用Supabase的用户ID作为Dexie-Cloud的userId userId: () => supabase.auth.user()?.id, // 自定义认证函数,用Supabase的令牌获取Dexie-Cloud访问权限 async getAccessToken() { const { data } = await supabase.auth.getSession(); return data.session?.access_token; }, // 从Supabase用户信息中提取邮箱存入userData userData: () => ({ email: supabase.auth.user()?.email }) } }); // 监听Supabase会话变化,同步Dexie-Cloud认证状态 supabase.auth.onAuthStateChange(async (event) => { if (event === 'SIGNED_IN' || event === 'SIGNED_OUT') { await db.cloud.sync(); } }); export default db;
4. 在Server Hooks中处理会话(src/hooks.server.js)
import { handleAuth } from '@supabase/auth-helpers-sveltekit'; export const handle = handleAuth();
5. 在页面组件中使用(src/routes/+page.svelte)
<script> import { supabase } from '$lib/supabaseClient'; import db from '$lib/db'; import { page } from '$app/stores'; let tasks = []; let newTaskTitle = ''; // 加载用户任务 async function loadTasks() { if ($page.data.session) { tasks = await db.tasks.where({ userId: $page.data.session.user.id }).toArray(); } } // 添加新任务 async function addTask() { if (newTaskTitle.trim() && $page.data.session) { await db.tasks.add({ title: newTaskTitle, done: false, userId: $page.data.session.user.id }); newTaskTitle = ''; await loadTasks(); } } // 登录/登出逻辑 async function signIn() { await supabase.auth.signInWithOAuth({ provider: 'google' }); } async function signOut() { await supabase.auth.signOut(); } $: loadTasks(); </script> <div> {#if $page.data.session} <button on:click={signOut}>登出</button> <h2>你的任务</h2> <input bind:value={newTaskTitle} placeholder="输入新任务" /> <button on:click={addTask}>添加任务</button> <ul> {#each tasks as task} <li>{task.title} - {task.done ? '已完成' : '未完成'}</li> {/each} </ul> {:else} <button on:click={signIn}>用Google登录</button> {/if} </div>
关键说明
- 集成的核心是让Dexie-Cloud使用Supabase的用户ID作为
userId,并通过Supabase的访问令牌完成Dexie-Cloud的认证; - 确保Dexie-Cloud的权限规则配置正确,只允许用户访问自己的数据(比如
tasks表的userId匹配当前用户ID); - 可以根据需要调整认证方式(比如邮箱密码登录代替OAuth)。
内容的提问来源于stack exchange,提问作者Jan-Jan
相关产品推荐
相关产品推荐

