修复:移除请求参数 projectId 降级,改为实时获取

根本原因:请求参数中的 projectId 是客户端缓存的,属于之前账户,
导致账户切换后使用错误的 projectId,返回 403 权限错误。

修改内容:
1. 移除对 request.project 的降级依赖
2. 当账户无 projectId 和 tempProjectId 时,实时调用 loadCodeAssist
3. 获取后缓存到 tempProjectId 供后续请求使用
4. 如果仍无法获取,返回 403 配置错误

影响端点:
- /v1internal:generateContent
- /v1internal:streamGenerateContent
This commit is contained in:
曾庆雷
2025-11-25 19:32:38 +08:00
parent e0500f0530
commit b619208970

View File

@@ -1104,21 +1104,46 @@ async function handleGenerateContent(req, res) {
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig) const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
// 智能处理项目ID优先使用配置的 projectId降级到临时 tempProjectId,最后使用请求参数 // 智能处理项目ID优先使用配置的 projectId降级到临时 tempProjectId
const effectiveProjectId = account.projectId || account.tempProjectId || project || null let effectiveProjectId = account.projectId || account.tempProjectId || null
// 如果没有任何项目ID尝试调用 loadCodeAssist 获取
if (!effectiveProjectId) {
try {
logger.info('📋 No projectId available, attempting to fetch from loadCodeAssist...')
const loadResponse = await geminiAccountService.loadCodeAssist(client, null, proxyConfig)
if (loadResponse.cloudaicompanionProject) {
effectiveProjectId = loadResponse.cloudaicompanionProject
// 保存临时项目ID
await geminiAccountService.updateTempProjectId(accountId, effectiveProjectId)
logger.info(`📋 Fetched and cached temporary projectId: ${effectiveProjectId}`)
}
} catch (loadError) {
logger.warn('Failed to fetch projectId from loadCodeAssist:', loadError.message)
}
}
// 如果还是没有项目ID返回错误
if (!effectiveProjectId) {
return res.status(403).json({
error: {
message:
'This account requires a project ID to be configured. Please configure a project ID in the account settings.',
type: 'configuration_required'
}
})
}
logger.info('📋 项目ID处理逻辑', { logger.info('📋 项目ID处理逻辑', {
accountProjectId: account.projectId, accountProjectId: account.projectId,
accountTempProjectId: account.tempProjectId, accountTempProjectId: account.tempProjectId,
requestProjectId: project,
effectiveProjectId, effectiveProjectId,
decision: account.projectId decision: account.projectId
? '使用账户配置' ? '使用账户配置'
: account.tempProjectId : account.tempProjectId
? '使用临时项目ID' ? '使用临时项目ID'
: project : '从loadCodeAssist获取'
? '使用请求参数'
: '不使用项目ID'
}) })
const response = await geminiAccountService.generateContent( const response = await geminiAccountService.generateContent(
@@ -1291,21 +1316,46 @@ async function handleStreamGenerateContent(req, res) {
const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig) const client = await geminiAccountService.getOauthClient(accessToken, refreshToken, proxyConfig)
// 智能处理项目ID优先使用配置的 projectId降级到临时 tempProjectId,最后使用请求参数 // 智能处理项目ID优先使用配置的 projectId降级到临时 tempProjectId
const effectiveProjectId = account.projectId || account.tempProjectId || project || null let effectiveProjectId = account.projectId || account.tempProjectId || null
// 如果没有任何项目ID尝试调用 loadCodeAssist 获取
if (!effectiveProjectId) {
try {
logger.info('📋 No projectId available, attempting to fetch from loadCodeAssist...')
const loadResponse = await geminiAccountService.loadCodeAssist(client, null, proxyConfig)
if (loadResponse.cloudaicompanionProject) {
effectiveProjectId = loadResponse.cloudaicompanionProject
// 保存临时项目ID
await geminiAccountService.updateTempProjectId(accountId, effectiveProjectId)
logger.info(`📋 Fetched and cached temporary projectId: ${effectiveProjectId}`)
}
} catch (loadError) {
logger.warn('Failed to fetch projectId from loadCodeAssist:', loadError.message)
}
}
// 如果还是没有项目ID返回错误
if (!effectiveProjectId) {
return res.status(403).json({
error: {
message:
'This account requires a project ID to be configured. Please configure a project ID in the account settings.',
type: 'configuration_required'
}
})
}
logger.info('📋 流式请求项目ID处理逻辑', { logger.info('📋 流式请求项目ID处理逻辑', {
accountProjectId: account.projectId, accountProjectId: account.projectId,
accountTempProjectId: account.tempProjectId, accountTempProjectId: account.tempProjectId,
requestProjectId: project,
effectiveProjectId, effectiveProjectId,
decision: account.projectId decision: account.projectId
? '使用账户配置' ? '使用账户配置'
: account.tempProjectId : account.tempProjectId
? '使用临时项目ID' ? '使用临时项目ID'
: project : '从loadCodeAssist获取'
? '使用请求参数'
: '不使用项目ID'
}) })
const streamResponse = await geminiAccountService.generateContentStream( const streamResponse = await geminiAccountService.generateContentStream(