FastAPI集成Bitbucket Connect App:用户/组织映射问题求助
核心问题分析
Bitbucket Connect App的installed事件默认不会携带FastAPI平台的用户/组织标识,直接重定向又不符合Bitbucket的响应要求,可通过以下合规方式实现关联:
方案1:安装URL携带自定义参数传递标识
在用户从FastAPI平台发起Bitbucket App安装请求时,将FastAPI的org_id/user_id作为自定义查询参数拼接到安装URL中,Bitbucket会在installed事件的payload里返回这些参数,从而实现关联。
具体步骤:
生成带参数的安装链接:
当用户在FastAPI平台点击"集成Bitbucket"按钮时,生成如下格式的安装URL(替换为你的App ID和实际标识):https://marketplace.atlassian.com/install/apps/你的AppID?host=bitbucket.org&fastapi_org_id=你的组织ID注:自定义参数避免使用Atlassian保留字段(如
host、state)。在
installed事件中获取并转发参数:
修改你的index.js代码,从installedpayload的settings字段中提取自定义参数,一起转发给FastAPI:app.post('/installed', (req, res) => { const payload = req.body; // 提取自定义参数(Bitbucket会把安装URL的自定义参数放到settings里) const fastapiOrgId = payload.settings?.fastapi_org_id; const forwardPayload = { ...payload, fastapi_org_id: fastapiOrgId }; fetch('https://bb63-43-248-153-252.ngrok-free.app/bitbucket/installed/webhook', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(forwardPayload) }) .then(response => { if (!response.ok) { console.error('Error forwarding to FastAPI:', response.statusText); res.sendStatus(500); } else { console.log('Successfully forwarded to FastAPI /installed'); res.sendStatus(200); } }) .catch(error => { console.error('Error forwarding to FastAPI:', error); res.sendStatus(500); }); });FastAPI端关联存储:
FastAPI收到转发的payload后,将Bitbucket返回的clientKey(Bitbucket安装实例的唯一标识)与fastapi_org_id关联存储,后续通过clientKey即可映射到对应的用户/组织。
方案2:利用Post-Install页面引导用户绑定
通过Connect App的postInstallPage配置,在安装完成后引导用户回到FastAPI平台完成绑定,既符合Bitbucket的响应要求,又能建立关联。
具体步骤:
修改Connect App配置:
在atlassian-connect.json中添加postInstallPage配置:{ // 原有配置不变 "postInstallPage": { "url": "/post-install", "key": "post-install-page" } }开发Post-Install页面:
在你的Connect App中新增/post-install路由,页面逻辑如下:- 通过Atlassian Connect JS API获取当前安装的
clientKey和installationId - 生成跳转链接到FastAPI的绑定页面,携带
clientKey参数:<!-- /post-install 页面示例 --> <script src="https://connect-cdn.atl-paas.net/all.js"></script> <script> window.addEventListener('load', () => { AP.context.getInstallations().then(installations => { const clientKey = installations[0].clientKey; // 跳转到FastAPI绑定页面,用户登录后完成关联 window.location.href = `https://你的FastAPI域名/bitbucket/bind?clientKey=${clientKey}`; }); }); </script>
- 通过Atlassian Connect JS API获取当前安装的
FastAPI端完成绑定:
FastAPI的/bitbucket/bind接口接收clientKey,在用户登录后,将当前用户的org_id/user_id与clientKey关联存储。
方案3:通过Bitbucket API信息反向匹配
在installed事件触发后,调用Bitbucket API获取安装对应的Workspace/用户信息,再让用户在FastAPI平台手动匹配或自动关联(如果已有存储的用户Bitbucket信息)。
具体步骤:
FastAPI调用Bitbucket API获取信息:
在FastAPI的/bitbucket/installed/webhook接口中,使用Connect App的凭证(clientKey和共享密钥)调用Bitbucket的Workspace接口:# FastAPI示例代码 import requests from jose import jwt from datetime import datetime, timedelta @app.post("/bitbucket/installed/webhook") async def handle_installed(payload: dict): client_key = payload["clientKey"] shared_secret = "你的Connect App共享密钥" # 生成JWT令牌用于调用Bitbucket API token = jwt.encode( {"iss": client_key, "exp": datetime.utcnow() + timedelta(minutes=10)}, shared_secret, algorithm="HS256" ) # 获取Workspace列表 response = requests.get( "https://api.bitbucket.org/2.0/workspaces", headers={"Authorization": f"JWT {token}"} ) workspaces = response.json()["values"] # 存储Workspace信息和clientKey save_to_db(client_key, workspaces) # 返回成功响应给Connect App return {"status": "success"}FastAPI平台提供匹配入口:
在FastAPI平台新增页面,让用户选择自己的Bitbucket Workspace,将其与当前用户的org_id/user_id关联绑定。
内容的提问来源于stack exchange,提问作者Abhey Sharma

