Next.js + Supabase 前后端分离登录实践


笔者是一名全栈偏后端的工程师。最近使用体验AI编辑器,写了一个简单的每日英文短文背诵小网站。

因为使用到了TTS服务,所以需要限制用户的使用频率,也就因此引入了简单的用户模块。

因为这个小网站太简单,所以我选择了nextjs + next auth + supabase + vercel这样一个免费的serverless方案。

这些功能代码的99%我都是使用Cursor或者Windsurf直接生成。

一开始也非常顺利,我在本机上访问一切正常,直到上线后,我把网站发给朋友,她说无法登录。我排查了一下,发现这个网站竟然需要科学上网才能登录。

经过排查,我发现,AI生成的代码,在登录的时候,是前端(浏览器)直接和supabase交互。

而按照我以往的直觉,我想当然得以为,肯定是用户发起登录请求,到我们部署的nextjs服务器,然后服务器和supabase来交互。

那么解决这个问题的大体思路,就是:

next auth 中的 CredentialsProvider 去访问服务器的一个接口,然后这个接口去请求supabase

设想很简单,但是实现起来,要了命了。因为我不熟悉supabase,这一块完全交给AI来实现,它反反复复地改了两天没改好。这里我也记录一下过程吧

首先打包的时候,你应该把一些配置写死

以下这两个变量,在打包前端的时候就要提供,而且必须写正确的值。对于后端开发来说,这是非常反直觉的一件事。然而这就是NEXT_PUBLIC变量的用处,SUPABASE中也提供了ANON和SERVICE ROLE两种key,其中ANON就是给前端用的,不怕暴漏,你只需要做好SUPABASE的权限控制。

NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=

可以把以上两个变量放到.env.build中,详见 https://github.com/travisbikkle/daily_english/blob/main/.env.build

如果你不这么做,你会遇到:

[cause]: [Error: getaddrinfo ENOTFOUND dummy] { errno: -3008, code: ‘ENOTFOUND’, syscall: ‘getaddrinfo’, hostname: ‘dummy’ }

具体如何实现防止前端直接和supabase交互

可以看着两个文件:

https://github.com/travisbikkle/daily_english/blob/main/src/lib/auth-config.ts
https://github.com/travisbikkle/daily_english/blob/main/src/app/api/auth/credentials/route.ts

发表评论