SIWE: Как реализовать идентификацию Ethereum для улучшения функциональности Dapp
SIWE(Вход с использованием Ethereum) это метод проверки идентификации пользователя на Эфире, аналогичный инициированию транзакции кошелька, используемый для подтверждения контроля пользователя над кошельком. Текущий процесс аутентификации стал очень простым, достаточно просто подписать информацию в плагине кошелька, большинство распространенных плагинов кошелька уже поддерживают это.
В данной статье в основном обсуждаются сценарии подписания на Ethereum, без упоминания других публичных цепей, таких как Solana и SUI.
Когда необходимо использовать SIWE
Если ваше Dapp имеет следующие требования, вы можете рассмотреть возможность использования SIWE:
Иметь свою собственную пользовательскую систему
Необходимо запросить информацию, связанную с конфиденциальностью пользователей
Но если ваш Dapp в основном предназначен для функции запроса, например, подобного приложению etherscan, то SIWE может быть не нужен.
Вы можете спросить, разве подключение кошелька на Dapp не доказывает право собственности на кошелек? Это утверждение частично верно. Для фронтенда подключение кошелька действительно указывает на идентификацию, но для вызовов API, требующих поддержки бэкенда, просто передача адреса недостаточна, потому что адрес является общедоступной информацией, и любой может "одолжить" его.
Принципы и процесс SIWE
Процесс SIWE можно охарактеризовать тремя шагами: подключение кошелька - подпись - получение идентификации. Давайте подробнее рассмотрим эти три шага.
Подключить кошелек
Это распространенная операция Web3, позволяющая подключить ваш кошелек в Dapp через плагин кошелька.
Подпись
Шаги подписи SIWE включают получение значения Nonce, подпись кошелька и проверку подписи на стороне сервера.
Сначала необходимо вызвать интерфейс backend для получения значения Nonce. После получения запроса backend сгенерирует случайное значение Nonce и свяжет его с текущим адресом, чтобы подготовиться к последующей подписи.
После получения значения Nonce на фронтенде, создается содержимое подписи, включая значение Nonce, доменное имя, идентификатор цепочки, содержимое подписи и т.д., обычно используется метод подписи, предоставляемый кошельком.
После создания подписи отправьте ее на сервер.
Получить идентификацию
После успешной проверки подписи на серверной стороне будет возвращен соответствующий идентификатор пользователя, например, JWT. При последующих запросах на сервер фронтенд должен указывать соответствующий адрес и идентификацию, чтобы подтвердить право собственности на кошелек.
Практика SIWE
Сейчас существует много компонентов и библиотек, которые поддерживают быстрое подключение кошелька и SIWE. Давайте проведем практическое занятие, цель которого — сделать так, чтобы ваш Dapp мог возвращать JWT для идентификации пользователя.
Обратите внимание, что этот пример предназначен только для ознакомления с основным процессом SIWE, его использование в производственной среде может представлять собой проблемы безопасности.
Подготовительные работы
Мы используем Next.js для разработки приложений, необходимо подготовить окружение Node.js. Преимущество использования Next.js заключается в том, что можно непосредственно разрабатывать полнофункциональные проекты, не разделяя фронтенд и бэкенд.
Установка зависимостей
Сначала установите Next.js, выполните в каталоге проекта:
NPX создать-следующий-app@14
После завершения установки по подсказкам, перейдите в каталог проекта и запустите:
npm run dev
Затем перейдите по адресу localhost:3000, чтобы увидеть, что базовый проект Next.js запущен.
Установка зависимостей, связанных с SIWE
Мы используем Ant Design Web3 для реализации SIWE, потому что он бесплатный, активно поддерживается, имеет опыт использования, похожий на обычную библиотеку компонентов, и поддерживает SIWE.
Ant Design Web3 SIWE зависит от библиотеки Wagmi. Мы импортируем соответствующий Provider в layout.tsx, чтобы весь проект мог использовать Hooks, предоставляемые Wagmi.
Сначала определите конфигурацию WagmiProvider:
JavaScript
"использовать клиент";
import { getNonce, verifyMessage } из "@/app/api";
import {
Основная сеть,
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();
Мы используем Provider, предоставленный Ant Design Web3, и определили некоторые интерфейсы SIWE, конкретная реализация будет представлена позже.
Затем добавьте кнопку подключения кошелька в качестве входа для фронтенда.
Таким образом, мы уже просто подключили 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 требует некоторые интерфейсы для помощи серверу в проверке идентификации пользователя. Давайте сейчас просто реализуем это.
Нонса
Nonce используется для генерации разных подписей при каждом подписании кошельком, что повышает надежность. Генерация Nonce должна быть связана с адресом, предоставленным пользователем, для повышения точности верификации.
Реализация Nonce очень проста, сначала генерируется случайная строка (, состоящая из букв и цифр ), затем nonce связывается с адресом:
JavaScript
import { randomBytes } из "crypto";
import { addressMap } from ".. /cache";
если (!address) {
throw new Error("Неверный адрес");
}
const nonce = randomBytes(16).toString("hex");
addressMap.set(адрес, nonce);
return Response.json({
данные: nonce,
});
}
signMessage
signMessage используется для подписи содержимого, обычно выполняется через плагин кошелька, мы обычно просто указываем метод. В этом примере используется метод подписи Wagmi.
проверитьСообщение
После подписи пользователю необходимо отправить содержимое до подписи вместе с подписью для проверки на сервер. Сервер извлекает содержимое из подписи для сравнения; если совпадает, это означает, что проверка прошла успешно.
Кроме того, необходимо провести проверку безопасности содержимого подписи, например, проверить, совпадает ли значение Nonce с тем, что было назначено пользователю. После успешной проверки вернуть пользователю JWT для последующей проверки прав доступа:
JavaScript
import { createPublicClient, 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(),
});
Таким образом, базовая реализация Dapp для входа с использованием SIWE была разработана.
Рекомендации по оптимизации
При выполнении входа с помощью SIWE, если используется узел RPC по умолчанию, процесс проверки может занять почти 30 секунд. Поэтому настоятельно рекомендуется использовать специализированные узловые сервисы для улучшения времени отклика интерфейса.
Получив HTTPS RPC соединение с основной сетью Ethereum, замените стандартный RPC для publicClient в коде:
JavaScript
const publicClient = createPublicClient({
цепочка: основная сеть,
транспорт: http('), //полученная служба узла RPC
});
После замены время проверки может значительно сократиться, а скорость интерфейса явно повысится.
This page may contain third-party content, which is provided for information purposes only (not representations/warranties) and should not be considered as an endorsement of its views by Gate, nor as financial or professional advice. See Disclaimer for details.
15 Лайков
Награда
15
6
Поделиться
комментарий
0/400
AirdropHustler
· 19ч назад
Ну, эта вещь считается довольно популярной, я уже давно ей пользуюсь.
Посмотреть ОригиналОтветить0
FallingLeaf
· 19ч назад
Подписывать - значит отдавать свою конфиденциальность? Дайте мне еще подумать.
Посмотреть ОригиналОтветить0
BearMarketMonk
· 19ч назад
идентификация? Очередной трюк, чтобы разыгрывать людей как лохов.
Руководство по реализации SIWE: улучшение функции идентификации Dapp
SIWE: Как реализовать идентификацию Ethereum для улучшения функциональности Dapp
SIWE(Вход с использованием Ethereum) это метод проверки идентификации пользователя на Эфире, аналогичный инициированию транзакции кошелька, используемый для подтверждения контроля пользователя над кошельком. Текущий процесс аутентификации стал очень простым, достаточно просто подписать информацию в плагине кошелька, большинство распространенных плагинов кошелька уже поддерживают это.
В данной статье в основном обсуждаются сценарии подписания на Ethereum, без упоминания других публичных цепей, таких как Solana и SUI.
Когда необходимо использовать SIWE
Если ваше Dapp имеет следующие требования, вы можете рассмотреть возможность использования SIWE:
Но если ваш Dapp в основном предназначен для функции запроса, например, подобного приложению etherscan, то SIWE может быть не нужен.
Вы можете спросить, разве подключение кошелька на Dapp не доказывает право собственности на кошелек? Это утверждение частично верно. Для фронтенда подключение кошелька действительно указывает на идентификацию, но для вызовов API, требующих поддержки бэкенда, просто передача адреса недостаточна, потому что адрес является общедоступной информацией, и любой может "одолжить" его.
Принципы и процесс SIWE
Процесс SIWE можно охарактеризовать тремя шагами: подключение кошелька - подпись - получение идентификации. Давайте подробнее рассмотрим эти три шага.
Подключить кошелек
Это распространенная операция Web3, позволяющая подключить ваш кошелек в Dapp через плагин кошелька.
Подпись
Шаги подписи SIWE включают получение значения Nonce, подпись кошелька и проверку подписи на стороне сервера.
Сначала необходимо вызвать интерфейс backend для получения значения Nonce. После получения запроса backend сгенерирует случайное значение Nonce и свяжет его с текущим адресом, чтобы подготовиться к последующей подписи.
После получения значения Nonce на фронтенде, создается содержимое подписи, включая значение Nonce, доменное имя, идентификатор цепочки, содержимое подписи и т.д., обычно используется метод подписи, предоставляемый кошельком.
После создания подписи отправьте ее на сервер.
Получить идентификацию
После успешной проверки подписи на серверной стороне будет возвращен соответствующий идентификатор пользователя, например, JWT. При последующих запросах на сервер фронтенд должен указывать соответствующий адрес и идентификацию, чтобы подтвердить право собственности на кошелек.
Практика SIWE
Сейчас существует много компонентов и библиотек, которые поддерживают быстрое подключение кошелька и SIWE. Давайте проведем практическое занятие, цель которого — сделать так, чтобы ваш Dapp мог возвращать JWT для идентификации пользователя.
Обратите внимание, что этот пример предназначен только для ознакомления с основным процессом SIWE, его использование в производственной среде может представлять собой проблемы безопасности.
Подготовительные работы
Мы используем Next.js для разработки приложений, необходимо подготовить окружение Node.js. Преимущество использования Next.js заключается в том, что можно непосредственно разрабатывать полнофункциональные проекты, не разделяя фронтенд и бэкенд.
Установка зависимостей
Сначала установите Next.js, выполните в каталоге проекта:
NPX создать-следующий-app@14
После завершения установки по подсказкам, перейдите в каталог проекта и запустите:
npm run dev
Затем перейдите по адресу localhost:3000, чтобы увидеть, что базовый проект Next.js запущен.
Установка зависимостей, связанных с SIWE
Мы используем Ant Design Web3 для реализации SIWE, потому что он бесплатный, активно поддерживается, имеет опыт использования, похожий на обычную библиотеку компонентов, и поддерживает SIWE.
Введите в терминале:
npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save
Введение Wagmi
Ant Design Web3 SIWE зависит от библиотеки Wagmi. Мы импортируем соответствующий Provider в layout.tsx, чтобы весь проект мог использовать Hooks, предоставляемые Wagmi.
Сначала определите конфигурацию WagmiProvider:
JavaScript "использовать клиент"; import { getNonce, verifyMessage } из "@/app/api"; import { Основная сеть, 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 siwe="{{" getnonce:="" async="" (address)=""> (ждать getNonce(адрес)).данные, createMessage: (props) => { return createSiweMessage({ ... props, statement: "Ant Design Web3" }); }, verifyMessage: async (сообщение, подпись) => { 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;
Мы используем Provider, предоставленный Ant Design Web3, и определили некоторые интерфейсы SIWE, конкретная реализация будет представлена позже.
Затем добавьте кнопку подключения кошелька в качестве входа для фронтенда.
Таким образом, мы уже просто подключили 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}; };
вернуть ( <> {(account) => ( <connectbutton.signin accountcomponent="{false}" renderbuttontext="{(dom)" ==""> renderSignBtnText(dom, account)} /> )} </connectbutton.signin> {jwt} ); }
Таким образом, мы реализовали самую простую структуру входа SIWE.
Реализация интерфейса
SIWE требует некоторые интерфейсы для помощи серверу в проверке идентификации пользователя. Давайте сейчас просто реализуем это.
Нонса
Nonce используется для генерации разных подписей при каждом подписании кошельком, что повышает надежность. Генерация Nonce должна быть связана с адресом, предоставленным пользователем, для повышения точности верификации.
Реализация Nonce очень проста, сначала генерируется случайная строка (, состоящая из букв и цифр ), затем nonce связывается с адресом:
JavaScript import { randomBytes } из "crypto"; import { addressMap } from ".. /cache";
экспортировать асинхронную функцию GET(request: Запрос) { const { searchParams } = новый URL(request.url); const address = searchParams.get("address");
если (!address) { throw new Error("Неверный адрес"); } const nonce = randomBytes(16).toString("hex"); addressMap.set(адрес, nonce); return Response.json({ данные: nonce, }); }
signMessage
signMessage используется для подписи содержимого, обычно выполняется через плагин кошелька, мы обычно просто указываем метод. В этом примере используется метод подписи Wagmi.
проверитьСообщение
После подписи пользователю необходимо отправить содержимое до подписи вместе с подписью для проверки на сервер. Сервер извлекает содержимое из подписи для сравнения; если совпадает, это означает, что проверка прошла успешно.
Кроме того, необходимо провести проверку безопасности содержимого подписи, например, проверить, совпадает ли значение Nonce с тем, что было назначено пользователю. После успешной проверки вернуть пользователю JWT для последующей проверки прав доступа:
JavaScript import { createPublicClient, 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(адрес)) { throw new Error("Неверный нонc"); }
// Проверка содержимого подписи const valid = await publicClient.verifySiweMessage({ сообщение, адрес, подпись, });
если (!valid) { throw new Error("Недействительная подпись"); }
// Генерация jwt и возврат const token = jwt.sign({ адрес }, JWT_SECRET, { expiresIn: "1h" }); return Response.json({ данные: токен, }); }
Таким образом, базовая реализация Dapp для входа с использованием SIWE была разработана.
Рекомендации по оптимизации
При выполнении входа с помощью SIWE, если используется узел RPC по умолчанию, процесс проверки может занять почти 30 секунд. Поэтому настоятельно рекомендуется использовать специализированные узловые сервисы для улучшения времени отклика интерфейса.
Получив HTTPS RPC соединение с основной сетью Ethereum, замените стандартный RPC для publicClient в коде:
JavaScript const publicClient = createPublicClient({ цепочка: основная сеть, транспорт: http('), //полученная служба узла RPC });
После замены время проверки может значительно сократиться, а скорость интерфейса явно повысится.