Next.js的getServerSideProps中Supabase策略不生效该如何解决?
问题原因
你在客户端调用Supabase接口时,SDK会自动携带当前登录用户的JWT凭证,请求会被行级访问策略正确识别身份,所以策略生效。
而服务端getServerSideProps运行在Node.js环境,你直接使用的全局Supabase实例默认是匿名身份,没有绑定当前请求对应的用户凭证,行级访问策略无法识别请求用户身份,因此匹配不到符合策略的数据,返回null。
解决步骤
- 在
getServerSideProps参数中取出当前请求对象req - 调用
supabase.auth.api.getUserByCookie(req)获取当前请求对应的用户凭证,无有效登录态可直接做重定向处理 - 调用
supabase.auth.setAuth()传入用户的access token,为当前Supabase实例绑定用户身份 - 再执行数据库查询操作,行级访问策略即可正常生效
修正后的代码示例
export const getServerSideProps: GetServerSideProps<BoardSlugProps> = async ({ query, req, // 新增:取出当前请求对象 }) => { // 1. 从Cookie中获取当前用户信息和凭证 const { user, error: authError } = await supabase.auth.api.getUserByCookie(req); // 无有效登录态可跳转到登录页 if (authError || !user) { return { redirect: { destination: '/login', permanent: false, }, }; } // 2. 为Supabase实例设置当前用户的access token supabase.auth.setAuth(user.access_token); // 3. 执行查询,此时行级访问策略会正常生效 const { data } = await supabase .from<BoardType>('board') .select('*') .eq('id', query.slug as string) .single(); return { props: { board: data, }, }; };
注意事项
如果你的项目是高并发场景,建议不要复用全局Supabase实例,每次在服务端请求时都初始化一个新的Supabase实例,再绑定用户凭证,避免不同请求的身份凭证互相串用导致安全问题。
内容的提问来源于stack exchange,提问作者Pedro Gómez
相关产品推荐
相关产品推荐

