如何在Nuxt3服务端通过Supabase实现认证、会话保持及数据获取
解决Nuxt3服务端Supabase登录后无法保留会话的问题
核心原因:服务端环境下,Supabase JS客户端没有浏览器的localStorage机制来自动持久化会话。调用signInWithPassword后,客户端不会保存会话状态,导致后续getSession返回null,且查询带行级安全(RLS)的表时无法通过认证校验。
解决方案
登录成功后,手动将返回的会话信息设置到Supabase客户端中,后续的数据库查询就会自动使用该会话进行认证,同时getSession也能获取到有效会话。
修改后的完整代码
import { createClient } from '@supabase/supabase-js' export default defineEventHandler(async (event) => { const body = await readBody(event) const { uid, pwd, order } = body // 创建Supabase客户端 const supabase = createClient( process.env.SUPABASE_URL, process.env.SUPABASE_KEY, ); // 用户登录 let { data, error } = await supabase.auth.signInWithPassword({ email: uid, password: pwd }) if (error) { return error } // 手动设置会话到客户端,这是关键步骤 await supabase.auth.setSession({ access_token: data.session.access_token, refresh_token: data.session.refresh_token }) const userId = data.user.id if (order === 'LED') { // 此时查询会自动使用已设置的会话,通过行级安全校验 let { data: reactor_runs, error: queryError } = await supabase .from('reactor_runs') .select('program') .eq('owner', userId) // 现在调用getSession就能拿到有效会话了 const { data: loggedSession, error: sessionError } = await supabase.auth.getSession() return { userId, order, queryError, accessToken: data.session.access_token, orderResponse: reactor_runs?.[0]?.program?.LED || null, loggedSession, sessionError } } else { return 'no result for your order' } })
补充说明
- 行级安全策略配置:确保你的
reactor_runs表RLS策略正确验证用户身份,示例SQL:
CREATE POLICY "仅允许用户查看自己的 reactor_runs" ON reactor_runs FOR SELECT USING (auth.uid() = owner);
- 会话生命周期:服务端每次请求都会创建新的Supabase客户端,会话仅在当前请求周期内有效,符合无状态服务端设计。
内容的提问来源于stack exchange,提问作者akemedis
相关产品推荐
相关产品推荐

