VS Code Web扩展中handleUri函数无法获取URI片段及登录弹窗API咨询
VS Code Web扩展OAuth2认证相关问题
概述
我正在开发一款基于OAuth2认证的VS Code Web扩展,和VS Code内置的GitHub认证流程逻辑类似。认证成功后,OAuth服务器会将页面重定向到指定的URI,但关键的认证凭证信息被附加在fragment部分(以#开头)。举个实际的重定向URI示例:
https://vscode.dev/callback?vscode-reqid=1&vscode-scheme=vscode&vscode-authority=myPublisher.foo-web-extension&vscode-path=%2Fdid-authenticate#&access_token=XXXX&expires_in=XXXX&location=XXXX&api_domain=XXXX
我在扩展源码里通过以下代码监听并处理这个重定向URI:
context.subscriptions.push(vscode.window.registerUriHandler({ handleUri(uri: vscode.Uri): vscode.ProviderResult<void> { console.log(uri); } })); // 实际输出:{ "$mid": 1, "path": "/did-authenticate", "scheme": "vscode", "authority": "myPublisher.foo-web-extension" }
可以看到,输出的vscode.Uri实例里完全缺失了fragment部分(也就是#&access_token=XXXX&expires_in=XXXX&location=XXXX&api_domain=XXXX),而这部分正是完成用户登录必需的核心凭证。
核心问题
- 问题1:我必须获取到URI中的OAuth凭证才能完成登录,有没有办法让
handleUri函数获取到URI的fragment部分?如果没有的话,有没有可行的替代方案? - 问题2:我当前用
vscode.env.openExternal启动登录流程,会打开一个新的浏览器标签页。但像GitHub认证那样用弹窗窗口来完成流程会更友好,我翻了VS Code扩展API文档没找到对应的方法,请问有没有实现弹窗登录的方式?
已尝试方案
我试过一个临时的测试思路:如果手动移除URI中的#,所有凭证信息就会被自动包含到uri.query对象中,这样就能正常获取到凭证了。所以我已经联系了OAuth服务提供商,请求他们调整重定向逻辑,把凭证信息从fragment移到查询字符串里,但目前还没得到明确的解决方案。
复现步骤
要在VS Code Web扩展开发中复现这个问题,可以按照以下步骤操作:
- 生成供扩展监听的重定向URI:
const redirectURI = (await vscode.env.asExternalUri(vscode.Uri.parse(vscode.env.uriScheme + '://myPublisher.foo-web-extension/did-authenticate'))).toString()
- 将生成的
redirectURI附加到OAuth2登录URI中,通过vscode.env.openExternal打开并完成认证:
const loginUri = await getLoginUri(redirectURI); await vscode.env.openExternal(loginUri);
- 注册URI处理方法监听事件,尝试获取并保存认证凭证:
context.subscriptions.push(vscode.window.registerUriHandler({ handleUri(uri: vscode.Uri): vscode.ProviderResult<void> { console.log(uri); } })); // 输出结果:{ "$mid": 1, "path": "/did-authenticate", "scheme": "vscode", "authority": "myPublisher.foo-web-extension" }
由于凭证信息位于重定向URI的fragment部分,最终获取到的uri对象中完全没有这部分内容,导致无法提取凭证完成登录。
环境信息
- VS Code Web版本:1.63.2
- Commit:899d46d82c4c95423fb7e10e68eba52050e30ba3
- User Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
- Embedder:vscode.dev
内容的提问来源于Stack Exchange,提问作者Adarsh Pandey




