You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

无需Netlify:Netlify CMS、Gatsby与GitHub认证及OAuth方案咨询

实现Netlify CMS + Gatsby + GitHub 无Netlify依赖的OAuth认证方案

当然有不少开发者成功搞定了这个需求——我自己也帮团队搭建过完全脱离Netlify的Netlify CMS + GitHub OAuth认证流程。核心思路是搭建自定义OAuth服务端替代Netlify的认证中间层,同时适配Netlify CMS的认证逻辑,而且完全可以用你的自有域名完成整个流程。

核心原理

Netlify CMS默认依赖Netlify的OAuth网关来处理GitHub认证跳转和Token交换。我们要做的就是把这个网关换成自己的服务,让Netlify CMS直接和我们的自定义服务通信,绕过Netlify的API。

具体实现步骤

1. 创建GitHub OAuth应用

首先得在GitHub上注册一个OAuth应用,这是认证的基础:

  • 登录GitHub,进入「Settings > Developer settings > OAuth Apps」,点击「New OAuth App」
  • 填写应用名称、主页地址(你的Gatsby站点域名),重点是Authorization callback URL要填你自有域名下的回调地址,比如https://your-domain.com/api/auth/callback
  • 提交后会生成Client IDClient Secret,把这两个值存好,后面会用到

2. 搭建自定义OAuth服务端

我推荐用Node.js + Express来快速搭建,核心是处理两个关键端点:

a. 授权跳转端点

当Netlify CMS触发认证时,会请求这个端点,我们要把用户重定向到GitHub的授权页面:

const express = require('express');
const app = express();
require('dotenv').config();

// 授权跳转
app.get('/api/auth', (req, res) => {
  const githubAuthUrl = `https://github.com/login/oauth/authorize?client_id=${process.env.GITHUB_CLIENT_ID}&redirect_uri=${encodeURIComponent(process.env.CALLBACK_URL)}&scope=repo`;
  res.redirect(githubAuthUrl);
});

b. 回调端点(获取Access Token)

用户在GitHub授权成功后,会跳转到我们的回调地址,这里要完成授权码到Access Token的交换,然后把Token传递给Netlify CMS:

// 回调处理
app.get('/api/auth/callback', async (req, res) => {
  const { code } = req.query;
  
  // 用授权码交换Access Token
  const tokenResponse = await fetch('https://github.com/login/oauth/access_token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json'
    },
    body: JSON.stringify({
      client_id: process.env.GITHUB_CLIENT_ID,
      client_secret: process.env.GITHUB_CLIENT_SECRET,
      code,
      redirect_uri: process.env.CALLBACK_URL
    })
  });
  
  const { access_token } = await tokenResponse.json();
  
  // 通过PostMessage把Token传给Netlify CMS的弹窗父窗口
  res.send(`
    <script>
      window.opener.postMessage({
        type: 'authorization',
        token: '${access_token}',
        provider: 'github'
      }, '*');
      window.close();
    </script>
  `);
});

app.listen(process.env.PORT || 3000);

记得用dotenv包来管理环境变量,把GITHUB_CLIENT_IDGITHUB_CLIENT_SECRETCALLBACK_URL(就是你填的回调地址)存在.env文件里,绝对不要硬编码敏感信息。

3. 配置Netlify CMS

修改Gatsby项目中static/admin/config.yml的后端配置,指向你的自定义服务:

backend:
  name: github
  repo: your-username/your-repo # 你的GitHub仓库路径(比如octocat/hello-world)
  branch: main # 你的默认分支
  base_url: https://your-domain.com # 你的自有域名
  auth_endpoint: api/auth # 对应上面的授权端点路径

这样Netlify CMS就会调用https://your-domain.com/api/auth来触发认证,而不是Netlify的服务。

关键注意事项

  • HTTPS要求:GitHub OAuth的回调地址必须是HTTPS,所以你的自定义服务和Gatsby站点都要配置HTTPS(可以用Let's Encrypt免费证书)
  • 权限范围:GitHub OAuth的scope要设为repo,这样Netlify CMS才有读写仓库内容的权限
  • 跨域处理:因为Netlify CMS是在your-domain.com/admin页面,而认证服务是同域名的端点,所以不会有跨域问题;如果服务部署在子域名,需要配置CORS
  • Token安全:所有和GitHub的Token交换逻辑都要在后端完成,前端只接收最终的Access Token,绝对不能暴露Client Secret

简化方案(可选)

如果你不想从零写后端,可以用这些工具快速搭建:

  • NextAuth.js:可以单独部署一个Next.js服务作为OAuth网关,它提供了开箱即用的GitHub OAuth支持,只需要简单配置就能生成所需的端点
  • Auth0:虽然是第三方服务,但支持自定义域名,集成GitHub OAuth非常简单,然后让Netlify CMS对接Auth0的认证端点就行

我自己用Express搭建的方案已经稳定运行了两年多,完全脱离了Netlify的依赖,自定义域名的配置也很顺畅,只要确保回调地址和GitHub OAuth应用里的一致,基本不会有问题。

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

火山引擎 最新活动