JavaScriptの
"クライアントを使用";
import type { Account } from "@ant-design/web3";
import { ConnectButton, Connector } from "@ant-design/web3";
import { Flex, Space } from "antd";
import React from "react";
import { JwtProvider } from "./JwtProvider";
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.
SIWE技術ガイド:Dappのためのイーサリアム身分証明システムの構築
SIWEテクニカルインプリメンテーションガイド:強力なDapp認証システムの構築
SIWE(イーサリアムでサインイン)は、ユーザーの身分証明をイーサリアム上で行う方法で、取引を開始するのに似ており、ユーザーがウォレットの制御権を持っていることを証明します。現在、主流のウォレットプラグインは、このシンプルな身分証明方法をサポートしており、プラグイン内で署名するだけで済みます。
この記事では、Ethereum上の署名シーンについて主に議論し、他のパブリックチェーンには触れません。
SIWEを使用する必要があるのはいつか
もしあなたのDappが以下の要件を持っている場合、SIWEの使用を検討してください:
クエリを主とするアプリケーション、例えばetherscanのようなブロックチェーンブラウザの場合、SIWEを使用する必要はありません。
Dappのフロントエンドでウォレットに接続した後、身分証明が行われたように見えますが、バックエンドサポートが必要なインターフェース呼び出しにおいて、アドレスを渡すだけでは不十分です。なぜなら、アドレスは公開情報であり、悪用されやすいからです。
! SIWEマニュアル:Dappをより強力にする方法は?
SIWEの原理とプロセス
SIWEプロセスは、3つのステップに要約できます: ウォレットの接続、サイン、身分証明の取得。
ウォレットを接続する
これは一般的なWeb3操作で、Dappでウォレットを接続するためにウォレットプラグインを使用します。
サイン
Nonce値の取得、ウォレット署名、バックエンド署名検証の3つのステップを含みます:
バックエンドからランダムに生成されたNonce値を取得し、現在のアドレスに関連付けます。
フロントエンドで署名内容を構築します。Nonce値、ドメイン名、チェーンIDなどの情報を含めて、ウォレットが提供する方法で署名します。
サインをバックエンドに送信して検証します。
ID を取得する
バックエンドで署名の検証が通過した後、ユーザーの身分証明(が返されます。JWT)のように。フロントエンドはその後のリクエストにアドレスと身分証明を持参すれば、ウォレットの所有権を証明できます。
! SIWEマニュアル:Dappをより強力にする方法は?
実践ガイド
以下は、NextjsプロジェクトでSIWE機能を実装し、身分証明のためにJWTを返す方法について説明します。
###環境の準備
npx create-next-app@14
npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save
! SIWEマニュアル:Dappをより強力にする方法は?
ワグミのご紹介
layout.tsx に WagmiProvider を導入します。
JavaScriptの "クライアントを使用する"; import { getNonce, verifyMessage } from "@/app/api"; インポート{ メインネット、 メタマスク Okxウォレット、 トークンポケット、 WagmiWeb3ConfigProvider、 ウォレットコネクト、 } から "@ant-design/web3-wagmi"; import { QueryClient } from "@tanstack/react-query"; import React from "react"; import { createSiweMessage } from "viem/siwe"; import { http } from "wagmi"; import { JwtProvider } from "./JwtProvider";
const YOUR_WALLET_CONNECT_PROJECT_ID = "c07c0051c2055890eade3556618e38a6"; const queryClient = 新しいQueryClient();
const WagmiProvider: React.FC = ({ children }) => { const [jwt, setJwt] = React.useState(null);
リターン( <wagmiweb3configprovider siwe="{{" getnonce:="" async="" (address)=""> (await getNonce(address)).data, createMessage: (props) => { 戻り値 createSiweMessage({ ... props, statement: "Ant Design Web3" }); }, verifyMessage:非同期(message、signature) = > { const jwt = (await verifyMessage(message、signature)).data; setJwt(jwt); 帰る!! JWTの; }, }} chains={[Mainnet]} transports={{ [Mainnet.id]:http()、 }} walletConnect={{ projectId: YOUR_WALLET_CONNECT_PROJECT_ID、 }} ウォレット={[} MetaMask()、 WalletConnect()、 TokenPocket({ グループ: "人気", }), OkxWallet()、 ]} queryClient={クエリクライアント} > {子供} ); };
export default WagmiProvider;
! SIWEマニュアル:Dappをより強力にする方法は?
接続ボタンを追加
コンポーネントにウォレット接続と署名ボタンを追加する:
JavaScriptの "クライアントを使用"; import type { Account } from "@ant-design/web3"; import { ConnectButton, Connector } from "@ant-design/web3"; import { Flex, Space } from "antd"; import React from "react"; import { JwtProvider } from "./JwtProvider";
export default 関数 App() { const jwt = React.useContext(JwtProvider);
const renderSignBtnText = ( defaultDom: React.ReactNode, アカウント?: アカウント ) => { const { アドレス } = アカウント ?? {}; const ellipsisAddress = アドレス ? ${address.slice(0, 6)}...${address.slice(-6)} : ""; ${ellipsisAddress}としてサインインします; };
リターン( <> <コネクタ renderSignBtnText="{renderSignBtnText}">
! SIWEマニュアル:Dappをより強力にする方法は?
インターフェース実装
Nonceインターフェース
JavaScriptの import { randomBytes } from "crypto"; import { addressMap } from ".. /cache";
非同期関数のエクスポート GET(request: Request) { const { searchParams } = 新しいURL(request.url); constアドレス= searchParams.get("アドレス");
if (!address) { 新しいError("無効なアドレス")をスローします。 } const nonce = randomBytes(16).toString("hex"); addressMap.set(住所、nonce); 戻り値 Response.json({ データ:nonce、 }); }
サイン検証インターフェース
JavaScriptの import { createPublicClient, http } from "viem"; import { mainnet } from "viem/chains"; "jsonwebtoken"からjwtをインポートする; import { parseSiweMessage } from "viem/siwe"; import { addressMap } from ".. /cache";
const JWT_SECRET = "あなたの秘密鍵";
const publicClient = createPublicClient({ チェーン: メインネット, トランスポート:http()、 });
export async 関数 POST(request: Request) { const {署名、メッセージ} = await request.json();
const { nonce, アドレス = "0x" } = parseSiweMessage(message);
if (!nonce || nonce !== addressMap.get(アドレス)) { 新しいError("無効なナンス")をスローします。 }
const valid = await publicClient.verifySiweMessage({ メッセージ、 アドレス、 署名 });
if (!valid) { 新しいError("無効な署名")をスローします。 }
const token = jwt.sign({ アドレス }, JWT_SECRET, { expiresIn: "1h" }); 戻り値 Response.json({ データ: トークン, }); }
! SIWEマニュアル:Dappをより強力にする方法は?
最適化の提案
SIWEのログイン速度を向上させるために、専用のノードサービスを使用することをお勧めします。ZANノードサービスを例にとり、EthereumメインネットのHTTPS RPC接続を取得した後、publicClientのデフォルトRPCを置き換えてください。
JavaScriptの const publicClient = createPublicClient({ チェーン: メインネット, transport: http('), //ZAN ノードサービス RPC });
これにより、検証時間を大幅に短縮し、インターフェースの応答速度を向上させることができます。
! SIWEマニュアル:Dappをより強力にする方法は?