ВVSCodeсуществуетнесколькоспособовхранитьнастройкипользователя.Доприходаверсии1.53.0конфиденциальнуюинформациюприходилосьсохранять вMementoобъектахв workspaceState и globalState илинапример keytar. А хранение паролей с токенами в стандартном конфигурационном файле или с помощью переменных окружения, являлось не самой лучшей идеей, так как эти данные могли быть прочитаны и кэшированы другими расширениями.
В статье мы посмотрим на способы чтения данных из
settings.json
и environment variables
. А
затем создадим класс с минимальным функционалом, отвечающий за
хранение и отдачу ключей со значениями из VSCode SecretStorage.
Проект мы условно назовем fancycolor
. Процесс
инициализации проекта подробно расписан в документации VSCode Extensions, поэтому
сразу приступим к интересному.
settings.json
Все настройки от всех VSCode extensions хранятся в общем файле
settings.json
и соответственно могут быть доступны из
любого расширения. К примеру, из нашего приложения
fancycolor
мы можем легко прочитать список всех хостов
и соответствующие им платформы из нашего конфига другого
популярного приложения SSH - Remote
.
const configurationWorkspace = workspace.getConfiguration()const sshRemotePlatform: string | undefined = configurationWorkspace.get( "remote.SSH.remotePlatform")console.log(sshRemotePlatform)
Данный код выведет список вашей конфигурации для расширения
SSH - Remote
.
Proxy {ubuntu: 'linux', home: 'linux', raspberry: 'linux'}
environment variables
VSCode расширения по умолчанию имеют доступ к переменным
окружения пользователя. Все переменные которые вы сохранили в
.bashrc
в Linux или User.Environment
в
Windows можно получить с помощью глобального объекта
process.env
.
Например создадим файл /home/ubuntu/.env
с
переменной ACCESS_TOKEN_ENV
и добавим его в
.bashrc
.
echo 'export ACCESS_TOKEN_ENV="d8aba3b2-fda0-414a-b867-4798b7892bb4"' >> /home/ubuntu/.envecho "source /home/ubuntu/.env" >> /home/ubuntu/.bashrc
В Windows тоже самое достигается через Powershell.
[System.Environment]::SetEnvironmentVariable('ACCESS_TOKEN_ENV', 'd8aba3b2-fda0-414a-b867-4798b7892bb4', [System.EnvironmentVariableTarget]::User)
Теперь прочитаем его в VSCode fancycolor
extension.
import * as process from "process"export const accessTokenEnv = process.env["ACCESS_TOKEN_ENV"]console.log(accessTokenEnv)
В выводе мы видим наш токен.
d8aba3b2-fda0-414a-b867-4798b7892bb4
SecretStorage
На сегодняшний день является лучшим способом хранения паролей,
логинов, токенов и другой конфиденциальной информации в VSCode. Для
демонстрации создадим простенький класс AuthSettings
,
где будем хранить fancycolor_token
, с минимально
необходимыми методами:
-
init
для инициализации нашего SecretStorage -
getter
instance
-
storeAuthData
для записи в SecretStorage -
getAuthData
для извлечения данных из SecretStorage
import { ExtensionContext, SecretStorage } from "vscode"export default class AuthSettings {private static _instance: AuthSettingsconstructor(private secretStorage: SecretStorage) {}static init(context: ExtensionContext): void {/*Create instance of new AuthSettings.*/AuthSettings._instance = new AuthSettings(context.secrets)}static get instance(): AuthSettings {/*Getter of our AuthSettings existing instance.*/return AuthSettings._instance}async storeAuthData(token?: string): Promise<void> {/*Update values in bugout_auth secret storage.*/if (token) {this.secretStorage.store("fancycolor_token", token)}}async getAuthData(): Promise<string | undefined> {/*Retrieve data from secret storage.*/return await this.secretStorage.get("fancycolor_token")}}
В extension.ts
напишем функционал позволяющий
добавлять и извлекать токен с помощью команд в Command Palette.
import * as vscode from "vscode"import AuthSettings from "./settings"export function activate(context: vscode.ExtensionContext) {// Initialize and get current instance of our Secret StorageAuthSettings.init(context)const settings = AuthSettings.instance// Register commands to save and retrieve tokenvscode.commands.registerCommand("fancycolor.setToken", async () => {const tokenInput = await vscode.window.showInputBox()await settings.storeAuthData(tokenInput)})vscode.commands.registerCommand("fancycolor.getToken", async () => {const tokenOutput = await settings.getAuthData()console.log(tokenOutput)})}export function deactivate() {}
Останется только в package.json
зарегистрировать
команды fancycolor.setToken
и
fancycolor.getToken
. В последствии при работе с VSCode
SecretStorage, мы сможем обратиться исключительно к конкретному
SecretStorage созданному для нашего приложения, которому будет
присвоен свой _id:
'undefined_publisher.fancycolor'
.