跳到主要内容

认证提供器和密钥存储怎么分工?

结论​

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,除非页面必须自己请求,并且你清楚过期和泄露窗口。多数情况由扩展代发请求。