认证提供器和密钥存储怎么分工?
结论
AuthenticationProvider 负责登录流程和会话,让别的插件通过统一的账户界面拿到令牌。secrets 是你自己插件用的加密键值存储。令牌可以放在认证会话里,由认证 API 保管;自己保存时放 secrets,不要放全局状态。
展开
自己调用现成登录:
const session = await vscode.authentication.getSession("github", ["repo"], {
createIfNone: true
});
这会走已经注册的 GitHub 认证,弹出统一登录,而不是每个插件自己做一套网页。
自己成为提供者时,实现 AuthenticationProvider:
getSessions返回已有会话createSession打开登录并返回新会话removeSession注销- 会话变化时触发
onDidChangeSessions
会话对象里的 accessToken 只在内存里交给调用方。落地存储要用编辑器提供的密钥能力,不要写进 globalState 或工作区文件。
secrets 适合没有必要暴露成「账户」的插件私有凭据,例如自己的刷新令牌:
await context.secrets.store("refreshToken", token);
const saved = await context.secrets.get("refreshToken");
它是异步的,按插件隔离。卸载插件时编辑器会处理对应密钥的清理语义,不要在普通文件里留备份。
网页和远程都要用这套 API,不要改成读本机 ~/.config 里的明文。界面侧和工作区侧的密钥存储不是你想象中随手共享的一个对象,令牌放在真正发起网络请求的那一侧读取。
容易讲错的点
- 认证提供者不替代 OAuth 实现本身。你仍要做授权码、刷新和过期,API 负责的是编辑器里的会话外形。
createIfNone: true会弹界面。静默读取用getSession的静默选项,没有会话就自己提示,不要在启动时强迫登录。- 令牌不要转发进 Webview,除非页面必须自己请求,并且你清楚过期和泄露窗口。多数情况由扩展代发请求。