SIWE: ключевая технология для повышения функциональности Dapp
SIWE (Вход с помощью Ethereum) — это метод проверки идентичности пользователей на Ethereum, аналогичный инициированию транзакции в кошельке, который подтверждает, что пользователь контролирует кошелек. Текущий процесс аутентификации очень прост: достаточно подписать информацию в плагине кошелька, и большинство распространенных плагинов кошельков уже поддерживают эту функцию.
В данной статье в основном рассматриваются сценарии подписей в Ethereum, без упоминания других блокчейнов, таких как Solana, SUI и т.д.
Нужно ли SIWE
Если ваше Dapp имеет следующие требования, вы можете рассмотреть возможность использования SIWE:
Иметь собственную пользовательскую систему
Необходимо узнать информацию, связанную с конфиденциальностью пользователя
Но если ваше Dapp в основном предназначено для функций запроса, например, для приложений, подобных etherscan, использование SIWE не обязательно.
Вы можете задаться вопросом, разве подключение кошелька к Dapp не доказывает право собственности на кошелек? Это утверждение частично верно. С точки зрения фронтенда, подключение кошелька действительно подтверждает личность, но для вызовов интерфейсов, требующих поддержки бэкенда, достаточно передать только адрес, потому что адрес является публичной информацией, и любой может "одолжить" его.
Принципы и процесс SIWE
Процесс SIWE можно обобщить в три шага: подключение кошелька - подпись - получение идентификатора личности. Давайте подробно рассмотрим эти три шага.
Подключить кошелек
Подключение кошелька — это распространенная операция Web3, которая позволяет подключать кошелек в Dapp через плагин кошелька.
Подпись
Шаги подписи в SIWE включают получение значения Nonce, подпись кошельком и проверку подписи на сервере.
Для получения значения Nonce необходимо вызвать интерфейс backend. После получения запроса backend сгенерирует случайное значение Nonce и свяжет его с текущим адресом, чтобы подготовиться к последующей подписи.
После получения значения Nonce на фронтенде необходимо сформировать содержимое подписи, включая значение Nonce, доменное имя, идентификатор цепочки, содержимое подписи и т.д. Обычно для подписи используется метод подписи, предоставленный кошельком.
После завершения создания подписи отправьте ее на сервер.
Получить идентификатор
После успешной проверки подписи на сервере будет возвращен идентификатор пользователя, такой как JWT. При последующих запросах на клиентской стороне необходимо предоставить соответствующий адрес и идентификатор, чтобы подтвердить право собственности на кошелек.
Практика
Сейчас существует множество компонентов и библиотек, которые поддерживают быстрое подключение кошельков и SIWE. Наша цель состоит в том, чтобы Dapp мог возвращать JWT для проверки идентификации пользователя. Обратите внимание, что этот демонстрационный пример предназначен только для представления основных процессов SIWE, использование в производственной среде может иметь проблемы с безопасностью.
Подготовительные работы
В этой статье используется Next.js для разработки приложений, необходима среда Node.js. Преимуществом использования Next.js является возможность разработки полноценного проекта без разделения на фронтенд и бэкенд.
Установка зависимостей
Сначала установите Next.js, выполните в каталоге проекта:
NPX создать-следующий-app@14
После завершения установки согласно инструкциям, перейдите в каталог проекта и выполните:
npm run dev
Согласно подсказке терминала, перейдите по адресу localhost:3000, чтобы увидеть основной проект Next.js.
Установка зависимостей SIWE
SIWE требует систему входа, поэтому необходимо подключить кошелек. Здесь мы используем Ant Design Web3, потому что:
Полностью бесплатно и активно поддерживается
В качестве библиотеки компонентов Web3, опыт использования похож на обычную библиотеку компонентов, без дополнительной умственной нагрузки.
Ant Design Web3 использует библиотеку Wagmi для реализации SIWE. Нам необходимо импортировать соответствующий Provider в layout.tsx, чтобы весь проект мог использовать Hooks, предоставляемые Wagmi.
Сначала определите конфигурацию WagmiProvider:
JavaScript
"использовать клиент";
импортировать { getNonce, verifyMessage } из "@/app/api";
импорт {
Основная сеть,
MetaMask
OkxWallet,
ТокенКарман,
WagmiWeb3ConfigProvider,
WalletConnect,
} из "@ant-design/web3-wagmi";
import { QueryClient } из "@tanstack/react-query";
импортировать React из "react";
import { createSiweMessage } из "viem/siwe";
import { http } из "wagmi";
import { JwtProvider } из "./JwtProvider";
const YOUR_WALLET_CONNECT_PROJECT_ID = "c07c0051c2055890eade3556618e38a6";
const queryClient = новый QueryClient();
Затем добавьте кнопку подключения кошелька, таким образом на фронтенде добавлен вход для подключения. На этом интеграция SIWE завершена, шаги очень простые.
Далее определите кнопку подключения, чтобы реализовать подключение кошелька и подпись:
JavaScript
"использовать клиент";
импортировать тип { Account } из "@ant-design/web3";
import { ConnectButton, Connector } из "@ant-design/web3";
import { Flex, Space } из "antd";
импортировать React из "react";
import { JwtProvider } из "./JwtProvider";
экспортировать по умолчанию функцию App() {
const jwt = React.useContext(JwtProvider);
const renderSignBtnText = (
defaultDom: React.ReactNode,
аккаунт?: Аккаунт
) => {
const { адрес } = аккаунт ?? {};
const ellipsisAddress = адрес
? ${address.slice(0, 6)}...${address.slice(-6)}
: "";
вернуться Войти как ${ellipsisAddress};
};
вернуть (
<>
{jwt}
);
}
Таким образом, реализована самая простая структура входа SIWE.
! [Руководство SIWE: Как сделать ваше децентрализованное приложение более мощным?] ](https://img-cdn.gateio.im/webp-social/moments-138fc08a9148099755d1fe162292922f.webp)
реализация интерфейса
SIWE нуждается в некоторых интерфейсах для помощи бэкенду в проверке идентичности пользователя. Теперь давайте реализуем это просто.
Нонс
Nonce используется для изменения содержимого, генерируемого кошельком при каждой подписи, увеличивая надежность подписи. Генерация Nonce должна быть связана с адресом, переданным пользователем, чтобы повысить точность проверки.
Реализация nonce очень проста, сначала генерируется случайная строка (, состоящая из букв и цифр ), затем связывается nonce и address:
JavaScript
импортировать { randomBytes } из "crypto";
import { addressMap } from ".. /cache";
если (!адрес) {
throw new Error("Неверный адрес");
}
const nonce = randomBytes(16).toString("hex");
addressMap.set(адрес, nonce);
return Response.json({
данные: nonce,
});
}
подписатьСообщение
signMessage используется для подписания содержимого, эта часть функционала обычно выполняется плагином кошелька, нам обычно не нужно настраивать это, достаточно просто указать метод. В этом демо используется метод подписи Wagmi.
проверитьСообщение
После того как пользователь подпишет, необходимо отправить содержимое до подписи вместе с подписью на сервер для проверки. Сервер извлекает соответствующее содержимое из подписи для сравнения, если совпадает, это означает, что проверка прошла успешно.
Кроме того, необходимо провести проверку безопасности содержимого подписи, например, соответствует ли значение Nonce в содержимом подписи тому, что было выдано пользователю и т.д. После успешной проверки необходимо вернуть пользователю JWT для дальнейшей проверки прав. Пример кода ниже:
JavaScript
импортировать { создатьПубличныйКлиент, http } из "viem";
import { mainnet } из "viem/chains";
импорт JWT из "jsonwebtoken";
import { parseSiweMessage } из "viem/siwe";
import { addressMap } from ".. /cache";
const JWT_SECRET = "your-secret-key"; // Пожалуйста, используйте более безопасный ключ и добавьте соответствующую проверку на истечение срока и т.д.
const publicClient = createPublicClient({
цепочка: основная сеть,
транспорт: http(),
});
если (!valid) {
throw new Error("Неверная подпись");
}
// Сгенерировать jwt и вернуть
const token = jwt.sign({ адрес }, JWT_SECRET, { expiresIn: "1h" });
return Response.json({
данные: токен,
});
}
На этом этапе базовое приложение Dapp с реализацией входа SIWE завершено.
Рекомендации по оптимизации
Использование узлов RPC по умолчанию для проверки входа SIWE может занять около 30 секунд, поэтому настоятельно рекомендуется использовать специализированные узловые сервисы для повышения времени отклика интерфейса. В этой статье используется узловой сервис ZAN, соответствующее соединение RPC можно получить из консоли узлового сервиса ZAN.
После получения HTTPS RPC соединения с основной сетью Ethereum замените RPC по умолчанию в publicClient в коде:
После замены время проверки значительно сократится, скорость интерфейса резко возрастет.
! [Руководство SIWE: Как сделать ваше децентрализованное приложение более мощным?] ](https://img-cdn.gateio.im/webp-social/moments-53c03d1cb26f29a9d739e3d1aa0816df.webp)
! [Руководство SIWE: Как сделать ваше децентрализованное приложение более мощным?] ](https://img-cdn.gateio.im/webp-social/moments-9351d7f08e48962120d591c3a0c7d245.webp)
! [Руководство SIWE: Как сделать ваше децентрализованное приложение более мощным?] ](https://img-cdn.gateio.im/webp-social/moments-0ce46cff7473e96e768adfb5fc6dafb8.webp)
На этой странице может содержаться сторонний контент, который предоставляется исключительно в информационных целях (не в качестве заявлений/гарантий) и не должен рассматриваться как поддержка взглядов компании Gate или как финансовый или профессиональный совет. Подробности смотрите в разделе «Отказ от ответственности» .
22 Лайков
Награда
22
8
Поделиться
комментарий
0/400
MeltdownSurvivalist
· 07-13 16:09
Безопасная верификация очень важна
Посмотреть ОригиналОтветить0
ForumMiningMaster
· 07-13 16:08
При проверке подписи необходимо соблюдать безопасность
Посмотреть ОригиналОтветить0
GateUser-cff9c776
· 07-10 16:45
Подпись слишком базовая.
Посмотреть ОригиналОтветить0
BoredStaker
· 07-10 16:41
Эта технология заслуживает глубокого изучения
Посмотреть ОригиналОтветить0
MEV_Whisperer
· 07-10 16:40
Информационная безопасность имеет первостепенное значение
Технология SIWE помогает Dapp улучшить идентификацию пользователей
SIWE: ключевая технология для повышения функциональности Dapp
SIWE (Вход с помощью Ethereum) — это метод проверки идентичности пользователей на Ethereum, аналогичный инициированию транзакции в кошельке, который подтверждает, что пользователь контролирует кошелек. Текущий процесс аутентификации очень прост: достаточно подписать информацию в плагине кошелька, и большинство распространенных плагинов кошельков уже поддерживают эту функцию.
В данной статье в основном рассматриваются сценарии подписей в Ethereum, без упоминания других блокчейнов, таких как Solana, SUI и т.д.
Нужно ли SIWE
Если ваше Dapp имеет следующие требования, вы можете рассмотреть возможность использования SIWE:
Но если ваше Dapp в основном предназначено для функций запроса, например, для приложений, подобных etherscan, использование SIWE не обязательно.
Вы можете задаться вопросом, разве подключение кошелька к Dapp не доказывает право собственности на кошелек? Это утверждение частично верно. С точки зрения фронтенда, подключение кошелька действительно подтверждает личность, но для вызовов интерфейсов, требующих поддержки бэкенда, достаточно передать только адрес, потому что адрес является публичной информацией, и любой может "одолжить" его.
Принципы и процесс SIWE
Процесс SIWE можно обобщить в три шага: подключение кошелька - подпись - получение идентификатора личности. Давайте подробно рассмотрим эти три шага.
Подключить кошелек
Подключение кошелька — это распространенная операция Web3, которая позволяет подключать кошелек в Dapp через плагин кошелька.
Подпись
Шаги подписи в SIWE включают получение значения Nonce, подпись кошельком и проверку подписи на сервере.
Для получения значения Nonce необходимо вызвать интерфейс backend. После получения запроса backend сгенерирует случайное значение Nonce и свяжет его с текущим адресом, чтобы подготовиться к последующей подписи.
После получения значения Nonce на фронтенде необходимо сформировать содержимое подписи, включая значение Nonce, доменное имя, идентификатор цепочки, содержимое подписи и т.д. Обычно для подписи используется метод подписи, предоставленный кошельком.
После завершения создания подписи отправьте ее на сервер.
Получить идентификатор
После успешной проверки подписи на сервере будет возвращен идентификатор пользователя, такой как JWT. При последующих запросах на клиентской стороне необходимо предоставить соответствующий адрес и идентификатор, чтобы подтвердить право собственности на кошелек.
Практика
Сейчас существует множество компонентов и библиотек, которые поддерживают быстрое подключение кошельков и SIWE. Наша цель состоит в том, чтобы Dapp мог возвращать JWT для проверки идентификации пользователя. Обратите внимание, что этот демонстрационный пример предназначен только для представления основных процессов SIWE, использование в производственной среде может иметь проблемы с безопасностью.
Подготовительные работы
В этой статье используется Next.js для разработки приложений, необходима среда Node.js. Преимуществом использования Next.js является возможность разработки полноценного проекта без разделения на фронтенд и бэкенд.
Установка зависимостей
Сначала установите Next.js, выполните в каталоге проекта:
NPX создать-следующий-app@14
После завершения установки согласно инструкциям, перейдите в каталог проекта и выполните:
npm run dev
Согласно подсказке терминала, перейдите по адресу localhost:3000, чтобы увидеть основной проект Next.js.
Установка зависимостей SIWE
SIWE требует систему входа, поэтому необходимо подключить кошелек. Здесь мы используем Ant Design Web3, потому что:
Выполните в терминале:
npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save
Введение в Wagmi
Ant Design Web3 использует библиотеку Wagmi для реализации SIWE. Нам необходимо импортировать соответствующий Provider в layout.tsx, чтобы весь проект мог использовать Hooks, предоставляемые Wagmi.
Сначала определите конфигурацию WagmiProvider:
JavaScript "использовать клиент"; импортировать { getNonce, verifyMessage } из "@/app/api"; импорт { Основная сеть, MetaMask OkxWallet, ТокенКарман, WagmiWeb3ConfigProvider, WalletConnect, } из "@ant-design/web3-wagmi"; import { QueryClient } из "@tanstack/react-query"; импортировать React из "react"; import { createSiweMessage } из "viem/siwe"; import { http } из "wagmi"; import { JwtProvider } из "./JwtProvider";
const YOUR_WALLET_CONNECT_PROJECT_ID = "c07c0051c2055890eade3556618e38a6"; const queryClient = новый QueryClient();
const WagmiProvider: React.FC = ({ дети }) => { const [jwt, setJwt] = React.useState(null);
вернуть ( <wagmiweb3configprovider: siweconfig="{{" getnonce:="" async="" (address)=""> (ожидать getNonce(адрес)).данные, createMessage: (props) => { return createSiweMessage({ ... props, statement: "Ant Design Web3" }); }, verifyMessage: async (message, signature) => { const jwt = (await verifyMessage(message, подпись)).data; setJwt(jwt); вернуть !!jwt; }, }} цепочки={[Mainnet]} transports={{ [Mainnet.id]: http(), }} walletConnect={{ projectId: YOUR_WALLET_CONNECT_PROJECT_ID, }} кошельки={[ MetaMask(), WalletConnect(), TokenPocket({ группа: "Популярные", }), OkxWallet(), ]} queryClient={queryClient} > {дети} ); };
экспорт по умолчанию WagmiProvider;
Затем добавьте кнопку подключения кошелька, таким образом на фронтенде добавлен вход для подключения. На этом интеграция SIWE завершена, шаги очень простые.
Далее определите кнопку подключения, чтобы реализовать подключение кошелька и подпись:
JavaScript "использовать клиент"; импортировать тип { Account } из "@ant-design/web3"; import { ConnectButton, Connector } из "@ant-design/web3"; import { Flex, Space } из "antd"; импортировать React из "react"; import { JwtProvider } из "./JwtProvider";
экспортировать по умолчанию функцию App() { const jwt = React.useContext(JwtProvider);
const renderSignBtnText = ( defaultDom: React.ReactNode, аккаунт?: Аккаунт ) => { const { адрес } = аккаунт ?? {}; const ellipsisAddress = адрес ? ${address.slice(0, 6)}...${address.slice(-6)} : ""; вернуться Войти как ${ellipsisAddress}; };
вернуть ( <>
Таким образом, реализована самая простая структура входа SIWE.
! [Руководство SIWE: Как сделать ваше децентрализованное приложение более мощным?] ](https://img-cdn.gateio.im/webp-social/moments-138fc08a9148099755d1fe162292922f.webp)
реализация интерфейса
SIWE нуждается в некоторых интерфейсах для помощи бэкенду в проверке идентичности пользователя. Теперь давайте реализуем это просто.
Нонс
Nonce используется для изменения содержимого, генерируемого кошельком при каждой подписи, увеличивая надежность подписи. Генерация Nonce должна быть связана с адресом, переданным пользователем, чтобы повысить точность проверки.
Реализация nonce очень проста, сначала генерируется случайная строка (, состоящая из букв и цифр ), затем связывается nonce и address:
JavaScript импортировать { randomBytes } из "crypto"; import { addressMap } from ".. /cache";
экспортировать асинхронную функцию GET(request: Запрос) { const { searchParams } = новый URL(request.url); const address = searchParams.get("address");
если (!адрес) { throw new Error("Неверный адрес"); } const nonce = randomBytes(16).toString("hex"); addressMap.set(адрес, nonce); return Response.json({ данные: nonce, }); }
подписатьСообщение
signMessage используется для подписания содержимого, эта часть функционала обычно выполняется плагином кошелька, нам обычно не нужно настраивать это, достаточно просто указать метод. В этом демо используется метод подписи Wagmi.
проверитьСообщение
После того как пользователь подпишет, необходимо отправить содержимое до подписи вместе с подписью на сервер для проверки. Сервер извлекает соответствующее содержимое из подписи для сравнения, если совпадает, это означает, что проверка прошла успешно.
Кроме того, необходимо провести проверку безопасности содержимого подписи, например, соответствует ли значение Nonce в содержимом подписи тому, что было выдано пользователю и т.д. После успешной проверки необходимо вернуть пользователю JWT для дальнейшей проверки прав. Пример кода ниже:
JavaScript импортировать { создатьПубличныйКлиент, http } из "viem"; import { mainnet } из "viem/chains"; импорт JWT из "jsonwebtoken"; import { parseSiweMessage } из "viem/siwe"; import { addressMap } from ".. /cache";
const JWT_SECRET = "your-secret-key"; // Пожалуйста, используйте более безопасный ключ и добавьте соответствующую проверку на истечение срока и т.д.
const publicClient = createPublicClient({ цепочка: основная сеть, транспорт: http(), });
экспортировать асинхронную функцию POST(запрос: Request) { const { подпись, сообщение } = ожидать запроса.json();
const { nonce, address = "0x" } = parseSiweMessage(message); console.log("nonce", nonce, адрес, addressMap);
// Проверка, совпадает ли значение nonce если (!nonce || nonce !== addressMap.get(адрес)) { выкинуть новый Error("Invalid nonce"); }
// Проверка содержания подписи const valid = await publicClient.verifySiweMessage({ сообщение, адрес, подпись, });
если (!valid) { throw new Error("Неверная подпись"); }
// Сгенерировать jwt и вернуть const token = jwt.sign({ адрес }, JWT_SECRET, { expiresIn: "1h" }); return Response.json({ данные: токен, }); }
На этом этапе базовое приложение Dapp с реализацией входа SIWE завершено.
Рекомендации по оптимизации
Использование узлов RPC по умолчанию для проверки входа SIWE может занять около 30 секунд, поэтому настоятельно рекомендуется использовать специализированные узловые сервисы для повышения времени отклика интерфейса. В этой статье используется узловой сервис ZAN, соответствующее соединение RPC можно получить из консоли узлового сервиса ZAN.
После получения HTTPS RPC соединения с основной сетью Ethereum замените RPC по умолчанию в publicClient в коде:
JavaScript const publicClient = createPublicClient({ цепочка: основная сеть, транспорт: http('), // Полученный ZAN узел сервис RPC });
После замены время проверки значительно сократится, скорость интерфейса резко возрастет.
! [Руководство SIWE: Как сделать ваше децентрализованное приложение более мощным?] ](https://img-cdn.gateio.im/webp-social/moments-53c03d1cb26f29a9d739e3d1aa0816df.webp)
! [Руководство SIWE: Как сделать ваше децентрализованное приложение более мощным?] ](https://img-cdn.gateio.im/webp-social/moments-9351d7f08e48962120d591c3a0c7d245.webp)
! [Руководство SIWE: Как сделать ваше децентрализованное приложение более мощным?] ](https://img-cdn.gateio.im/webp-social/moments-0ce46cff7473e96e768adfb5fc6dafb8.webp)