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}`); });
额外配置说明
- 安装
dotenv包:执行npm install dotenv,用于加载环境变量 - 创建
.env文件,添加内容:
GITHUB_TOKEN=你的个人访问令牌
- 将
.env文件添加到.gitignore中,避免提交到代码仓库泄露令牌
内容的提问来源于stack exchange,提问作者Praveen
相关产品推荐
相关产品推荐

