Next.js 提供了接口路由功能,可以用来添加一些简单的接口,我们可以利用 Github Oauth + JWT 实现一个简易的 Next.js 用户认证系统。(如果的你的网站只是使用 next.js 生成静态网站,然后部署到 Static hosting,例如 Github Pages,则无法运行 Next.js 接口路由功能)
Github 登录
首先我们需要创建一个用于登录的 Github Oauth App,点击这里创建,其中 Authorization callback URL 请填写 http://localhost:3000/api/oauth/github/callback (上线后请创建一个新的应用填写线上的地址)
获取到 Client id 和 Client Secret 后写入到本地的环境变量配置文件 .env.local
, 对应的 key 为 GITHUB_CLIENT_ID
, GITHUB_SECRET
跳转用户到 Github 授权
Oauth 认证的第一步,需要跳转用户到对应的第三方网站进行应用授权,我们使用一个固定的链接,直接跳转到 Github 授权。
首先在环境变量文件中添加 NEXT_PUBLIC_SITE_URL
用于区别开发和线上的访问链接,本地的值为 http://localhost:3000
, 然后创建文件 /pages/api/connect/github.ts
这样用户访问 /api/connect/github
就会跳转到 Github 授权页面
获取 Github 用户信息
Oauth 后面的步骤就是用户完成授权后,会跳转回我们在应用注册时填写的 Authorization callback URL
,在页面 URL 中会加上 code 参数,使用 code 参数获取到 access_token, 然后利用 access_token 访问接口数据。
关于 Github Oauth 详细文档请参考 Authorizing OAuth Apps
创建 /pages/api/oauth/github/callback.ts
我们使用新窗口完成 Github 认证,在获取到 Github 用户数据后,将数据加密后存储在 cookie 中,同时在请求响应中通过 postMessage 把用户数据传递到当前页面,完成后自动关闭认证页面,这样在不刷新页面的情况下完成用户认证。
JWT 加密
由于我们并不使用数据库存储用户数据,而是直接将用户数据存储在 cookie 中,所以我们需要做一层加密,最常见的方式就是使用 JWT(JSON Web Tokens)
首先在环境变量文件中添加 JWT_SECRET
加密密码,然后创建 /lib/jwt.ts
用户认证
用户验证
添加接口读取 cookie 中用户数据,创建 /pages/api/user.ts
用户退出
添加接口清除用户 cookie 即可退出用户登录,创建 /pages/api/logout.ts
用户上下文(React Context)
完成后端接口后,我们创建上下文处理用户认证,创建文件 /context/auth/provider.tsx
更新 /pages/_app.tsx
文件
这样我们在任意页面和组件使用上下文,获取当前登录用户,调用登录、退出方法。
在登录环节可以把 Github 换成其他任何第三方,或者使用 passport.js 做处理。