You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vite+React项目中Supabase未在localStorage存储会话数据问题

Vite+React+Supabase 会话无法持久化到localStorage问题排查

问题描述

使用Vite+React+Supabase搭建的应用,注册/登录功能表面正常,但会话数据未存储到localStorage,导致页面刷新后用户丢失认证状态。Supabase后台已确认用户创建/登录成功,但自定义的useAuth Hook始终返回null会话。

现有代码

supabaseClient.js

import { createClient } from '@supabase/supabase-js'

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey)

useAuth Hook

import { useEffect, useState } from "react"
import { supabase } from "../supabaseClient"

export default function useAuth () {
    const [session, setSession] = useState(null)

    useEffect(() => {
        supabase.auth.getSession().then(({ data: { session } }) => {
          setSession(session)
        })
    
        supabase.auth.onAuthStateChange((_event, session) => {
          setSession(session)
        })
      }, [])

    console.log('session ', session)

    return {
        session
    }
}

排查与解决方案

1. 显式配置Supabase客户端的会话持久化

默认情况下Supabase应自动使用localStorage,但Vite环境下可能需要显式指定配置,确保会话持久化逻辑生效:
修改supabaseClient.js:

import { createClient } from '@supabase/supabase-js'

const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY

export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
  auth: {
    storage: window.localStorage,
    persistSession: true, // 强制开启会话持久化
    autoRefreshToken: true,
    detectSessionInUrl: true
  }
})

2. 验证环境变量加载是否正确

Vite环境变量需以VITE_为前缀,确认根目录.env文件中的VITE_SUPABASE_URL和VITE_SUPABASE_ANON_KEY无拼写错误,且已重启Vite开发服务器。可临时在supabaseClient.js中打印变量值验证:

console.log('Supabase URL:', supabaseUrl)
console.log('Supabase Anon Key:', supabaseAnonKey)

若输出undefined,说明环境变量未正确加载,检查.env文件路径和命名规范。

3. 完善useAuth Hook的会话监听逻辑

当前Hook未清理onAuthStateChange的订阅,可能导致内存泄漏,同时优化初始会话获取的异步处理:
修改useAuth.js:

import { useEffect, useState } from "react"
import { supabase } from "../supabaseClient"

export default function useAuth () {
    const [session, setSession] = useState(null)

    useEffect(() => {
        // 异步获取初始会话
        const fetchInitialSession = async () => {
            const { data: { session } } = await supabase.auth.getSession()
            setSession(session)
        }
        fetchInitialSession()

        // 订阅认证状态变化,返回清理函数
        const { data: { subscription } } = supabase.auth.onAuthStateChange((_event, session) => {
            setSession(session)
        })

        return () => subscription.unsubscribe()
    }, [])

    return {
        session
    }
}

4. 检查浏览器隐私设置

若浏览器开启"阻止第三方Cookie"或处于隐私模式,可能会限制localStorage的写入。切换到普通浏览器模式,检查开发者工具Application标签下的localStorage是否存在sb-xxx-auth-token开头的键值对。

5. 确认注册/登录的调用方式

确保使用Supabase官方认证方法触发会话持久化,示例:

  • 注册:
const { data, error } = await supabase.auth.signUp({
  email: 'user@example.com',
  password: 'your-password'
})
  • 登录:
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'your-password'
})

避免使用自定义认证流程导致会话未被正确存储。


内容的提问来源于stack exchange,提问作者Kyle Pendergast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 06:25:15