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

Node.js调用GitHub Commits API访问私有仓库报404的解决方法

解决Octokit访问私有GitHub仓库返回"notfound"的问题

问题背景

开发基于Node.js+Express+Octokit的API,用于调用GitHub Commits相关接口、列出提交记录。公开仓库下API运行正常,但仓库转为私有后接口返回"notfound"错误,已拥有该仓库的访问权限,需解决API传递凭证的问题。

解决方案

1. 生成具备私有仓库访问权限的个人访问令牌(PAT)

GitHub私有仓库需要通过**个人访问令牌(PAT)**验证权限,邮箱无法直接作为凭证使用。生成步骤:

  • 登录GitHub,进入Settings → Developer settings → Personal access tokens → Tokens (classic)
  • 生成新令牌,勾选repo权限(访问私有仓库必需),设置有效期
  • 复制生成的令牌,妥善保存(仅显示一次)

2. 正确配置Octokit凭证

  • 避免硬编码令牌,用环境变量存储(比如process.env.GITHUB_TOKEN),防止令牌泄露
  • 全局初始化Octokit实例,无需在每个接口中重复创建,提升效率

3. 修复代码中的错误

原代码存在几个问题:

  • 重复创建Octokit实例,冗余且低效
  • /api/commit/details/:sha接口错误使用req.params.ref,路由参数实际是sha而非ref
  • 硬编码令牌存在安全风险

修改后的完整代码

require('dotenv').config();
const express = require('express');
const { Octokit } = require('@octokit/core');

const app = express();
const port = 3000;

// 全局初始化Octokit实例,复用凭证
const octokit = new Octokit({
  auth: process.env.GITHUB_TOKEN, // 从环境变量读取令牌
});

// 通用仓库配置,统一管理避免重复代码
const REPO_CONFIG = {
  owner: 'Praveenkumarsaravana',
  repo: 'django',
  headers: {
    'X-GitHub-Api-Version': '2022-11-28',
  },
};

app.get('/api/commits', async (req, res) => {
  try {
    const response = await octokit.request('GET /repos/{owner}/{repo}/commits', REPO_CONFIG);
    res.json(response.data);
  } catch (error) {
    console.error('获取提交记录失败:', error.message);
    console.error('错误详情:', error.response?.data);
    res.status(error.response?.status || 500).json({ 
      error: error.response?.data?.message || 'Internal Server Error' 
    });
  }
});

app.get('/api/commit/:sha/branches', async (req, res) => {
  try {
    const response = await octokit.request('GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head', {
      ...REPO_CONFIG,
      commit_sha: req.params.sha,
    });
    res.json(response.data);
  } catch (error) {
    console.error('获取提交关联分支失败:', error.message);
    res.status(error.response?.status || 500).json({ 
      error: error.response?.data?.message || 'Internal Server Error' 
    });
  }
});

app.get('/api/commit/:sha/pulls', async (req, res) => {
  try {
    console.log('收到请求: /api/commit/:sha/pulls');
    const response = await octokit.request('GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls', {
      ...REPO_CONFIG,
      commit_sha: req.params.sha,
    });
    res.json(response.data);
  } catch (error) {
    console.error('获取提交关联PR失败:', error.message);
    res.status(error.response?.status || 500).json({ 
      error: error.response?.data?.message || 'Internal Server Error' 
    });
  }
});

app.post('/api/commit/details/:sha', async (req, res) => {
  try {
    const response = await octokit.request('GET /repos/{owner}/{repo}/commits/{ref}', {
      ...REPO_CONFIG,
      ref: req.params.sha, // 修正参数,路由参数为sha
    });
    res.json(response.data);
  } catch (error) {
    console.error('获取提交详情失败:', error.message);
    res.status(error.response?.status || 500).json({ 
      error: error.response?.data?.message || 'Internal Server Error' 
    });
  }
});

app.post('/api/compare/:basehead', async (req, res) => {
  try {
    const response = await octokit.request('GET /repos/{owner}/{repo}/compare/{basehead}', {
      ...REPO_CONFIG,
      basehead: req.params.basehead,
    });
    res.json(response.data);
  } catch (error) {
    console.error('比较提交差异失败:', error.message);
    res.status(error.response?.status || 500).json({ 
      error: error.response?.data?.message || 'Internal Server Error' 
    });
  }
});

app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

额外配置说明

  1. 安装dotenv包:执行npm install dotenv,用于加载环境变量
  2. 创建.env文件,添加内容:
GITHUB_TOKEN=你的个人访问令牌
  1. 将.env文件添加到.gitignore中,避免提交到代码仓库泄露令牌

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 10:32:37