Аутентификация — это то, что мы обычно связываем со связью клиент-сервер, способ для пользователя сообщить серверу, что у него действительно есть права доступа к его данным.

Приложение Concord не взаимодействует с сервером и не имеет доступа к централизованной базе данных, но нам по-прежнему нужен способ добавить удостоверение в наши приложения.

Чтобы обеспечить безопасную идентификацию, мы можем использовать Web Crypto API для создания пары открытого/закрытого ключей и добавить немного сахара с API композиции Vue 3, чтобы добавить простой, но эффективный поток аутентификации в наши приложения.

https://github.com/teamconcords/offline-аутентификация

Мы собираемся выдавать пару ключей открытый/закрытый через Web Crypto API, используя ECDSA (алгоритм цифровой подписи на эллиптических кривых). Это позволит использовать подпись и проверку транзакций, используя хэш закрытого ключа, связанный с общедоступной личностью.

const { publicKey, privateKey } = await crypto.subtle.generateKey({
  name: "ECDSA",
  namedCurve: "P-384",
}, true, ["sign", "verify"]);

Теперь, когда мы создали нашу пару ключей, нам нужно экспортировать ключ для использования в нашем приложении. Мы собираемся использовать тип JWK для наших экспортных ключей, чтобы мы могли реализовать знакомый поток аутентификации для нашего приложения.

const { exportKey } = crypto.subtle;
const encodedPublicKey = exportKey('jwk', publicKey);
const encodedPrivateKey = exportKey('jwk', privateKey);

В формате ключа JWK оба ключа разделяют открытый аспект ключа, здесь для нас важен открытый ключ и атрибут encodedPrivateKey.d закрытого ключа. Пока у нас есть открытый ключ и уникальный JWK, хранящийся в encodedPrivateKey.d, мы можем создать уникальный ключ подписи для идентификации, если мы аутентифицированы в приложении.

Чтобы создать ключ подписи, мы можем объединить открытый ключ с нашим JWK и передать операцию ключа "sign" методу importKey WebCrypto API.

const key = { ...encodedPublicKey, d: jwk };

crypto.subtle.importKey(
  'jwk',
  key,
  {
    name: 'ECDSA',
    namedCurve: "P-384",
  },
  true,
  ["sign"],
);

Вместе этот модуль дает нам возможность создать новую пару ключей и имитировать вход в систему путем проверки подписи ключа. Теперь мы можем поместить все это в наш модуль аутентификации, готовый к подключению к нашему пользовательскому интерфейсу.

// authentication.js
export const create = async () => {
  const { publicKey, privateKey } = await crypto.subtle.generateKey(
    { name: "ECDSA", namedCurve: "P-384" },
    true,
    ["sign", "verify"]
  );
  const encodedPublicKey = await crypto.subtle.exportKey('jwk', publicKey);
  const encodedPrivateKey = await crypto.subtle.exportKey('jwk', privateKey);
  const jwk = encodedPrivateKey.d;
  return {
    jwk,
    key: encodedPublicKey,
  };
};

export const login = (jwk, key) => {
  if (!jwk) {
    return;
  }
  delete key.key_ops;
  return crypto.subtle.importKey(
    'jwk',
    { ...key, d: jwk },
    { name: 'ECDSA', namedCurve: "P-384" },
    true,
    ["sign"],
  );
};

Во Части 2 мы расскажем, как подключить автономный поток аутентификации к Vue 3 Composition API, чтобы создать полный автономный поток аутентификации.

Часть 2: https://concords.medium.com/offline-authentication-in-the-browser-part-2-hooking-up-ui-with-the-vue-3-composition-api-86ae0e7d31e5

Демо: https://offline-authentication.concords.app.

Источник: https://github.com/teamconcords/offline-authentication