# SIWE:あなたのDappの身分証明をより安全で信頼できるものにするSIWE(Ethereumでのサインイン)は、ユーザーの身分証明をEthereum上で検証する方法で、ウォレットがトランザクションを発起するのに似ており、ユーザーがそのウォレットに対する制御権を持っていることを証明するために使用されます。現在、主流のウォレットプラグインはこのシンプルな身分証明方式をサポートしており、情報に対してウォレット内で署名するだけで済みます。本文は、Ethereum上のSIWE署名シナリオについて主に議論し、Solana、SUIなどの他のパブリックブロックチェーンには触れません。## SIWEはいつ使用する必要がありますか?もしあなたのDappが以下の要件を持っている場合、SIWEの使用を検討できます:- 独立したユーザーシステムを持つ- ユーザーのプライバシーに関連する情報を確認する必要がありますクエリ機能を主とするDapp(、例えばブロックエクスプローラー)の場合、必ずしも身分証明は必要ではありません。あなたは疑問に思うかもしれませんが、ウォレットを通じてDappに接続した後、すでにウォレットの所有権が示されているのではないでしょうか?この言い方は完全に正確ではありません。フロントエンドにとっては、ウォレットの接続は確かに身分を証明できますが、バックエンドのサポートが必要なインターフェース呼び出しにおいては、アドレスを渡すだけでは身分を検証することはできません。なぜなら、アドレスは公開情報だからです。! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-9e9c9e786391f84b004cd8450a29acce)## SIWEの原理とプロセスSIWEのプロセスは、3つのステップに要約できます: ウォレットを接続 - サイン - 身分証明を取得。これらの3つのステップについて詳しく見てみましょう:### ウォレットを接続するこれは一般的なWeb3操作であり、ウォレットプラグインを通じてDappにユーザーのウォレットを接続できます。### サインSIWEの署名ステップには、Nonce値の取得、ウォレット署名、およびバックエンド署名検証が含まれます。まず、バックエンドのインターフェースを呼び出してNonce値を取得する必要があります。バックエンドはランダムなNonceを生成し、現在のアドレスに関連付けて、後続の署名の準備をします。フロントエンドがNonce値を取得した後、Nonce、ドメイン名、チェーンID、署名内容などを含む署名内容を構築します。そして、ウォレットが提供する署名メソッドを使用して内容に署名します。最後に署名をバックエンドに送信して検証します。### ID を取得する バックエンドが署名の検証に成功した後、対応するユーザー身分証明が返されます。通常はJWTトークンです。フロントエンドはその後のリクエストでアドレスと身分証明を持参することで、ウォレットの所有権を証明できます。! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-138fc08a9148099755d1fe162292922f)## SIWEの実践私たちは実際の操作を通じてSIWE機能を実現できます。目的は、Dappがユーザーの身分証明のためにJWTを返すことです。注意が必要です。以下のデモは基本的なプロセスを示すためのものであり、本番環境ではセキュリティのリスクが存在する可能性があります。###の準備この記事では、Next.jsを使用してアプリケーションを開発するためにNode.js環境を準備する必要があります。Next.jsの利点は、フロントエンドとバックエンドを分割することなく、フルスタックプロジェクトを直接開発できることです。### 依存関係をインストールするまず、Next.jsをインストールします:npx create-next-app@14提示に従ってインストールを完了したら、プロジェクトディレクトリに入り、プロジェクトを起動します:npm run dev### SIWEに関連する依存関係をインストールする私たちは、ウォレット接続とSIWE機能を実現するためにAnt Design Web3コンポーネントライブラリを使用しています:npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save ### ワグミのご紹介Ant Design Web3のSIWEはWagmiライブラリに依存しています。layout.tsxで関連するProviderを導入し、プロジェクト全体でWagmiが提供するHooksを使用できるようにします。まず、WagmiProvider 構成を定義します。JSXの"クライアントを使用する";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 siweconfig="{{" 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={クエリクライアント} > <jwtprovider.provider value="{jwt}">{children}</jwtprovider.provider> </wagmiweb3configprovider> );};export default WagmiProvider;! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-355ea961b315585f7d217cbcf6a3fa69)次に、ウォレット接続ボタンを追加します:JSXの"クライアントを使用する";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}としてサインインします; }; リターン( <> <flex vertical="" gap="middle"> <space> <connectbutton> <connector renderconnected="{renderSignBtnText}"> </connector></connectbutton></space> <div>JWT: {jwt}</div> </flex> <!----> );}これで、私たちはシンプルなSIWEログインフレームワークを実現しました。! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-53c03d1cb26f29a9d739e3d1aa0816df)### インターフェースの実装#### ノンス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、 });}#### メッセージを確認するバックエンドは署名内容を検証し、後続の権限検証に使用するJWTを返す必要があります: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をより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-18a98c883797c414a689c54ae0d65302)## 最適化の提案SIWEログイン速度を向上させるために、インターフェース応答時間を短縮する専用のノードサービスを使用することをお勧めします。ZANなどのノードサービスを使用して、対応するRPC接続を取得し、コード内のデフォルトRPCを置き換えてください。JavaScriptのconst publicClient = createPublicClient({ チェーン: メインネット, transport: http('), //ZAN ノードサービス RPC});これにより、検証時間を大幅に短縮し、インターフェースの速度を向上させることができます。! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-9351d7f08e48962120d591c3a0c7d245)! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-0ce46cff7473e96e768adfb5fc6dafb8)
SIWE認証:Dappsのセキュリティを向上させるための重要なテクノロジー
SIWE:あなたのDappの身分証明をより安全で信頼できるものにする
SIWE(Ethereumでのサインイン)は、ユーザーの身分証明をEthereum上で検証する方法で、ウォレットがトランザクションを発起するのに似ており、ユーザーがそのウォレットに対する制御権を持っていることを証明するために使用されます。現在、主流のウォレットプラグインはこのシンプルな身分証明方式をサポートしており、情報に対してウォレット内で署名するだけで済みます。
本文は、Ethereum上のSIWE署名シナリオについて主に議論し、Solana、SUIなどの他のパブリックブロックチェーンには触れません。
SIWEはいつ使用する必要がありますか?
もしあなたのDappが以下の要件を持っている場合、SIWEの使用を検討できます:
クエリ機能を主とするDapp(、例えばブロックエクスプローラー)の場合、必ずしも身分証明は必要ではありません。
あなたは疑問に思うかもしれませんが、ウォレットを通じてDappに接続した後、すでにウォレットの所有権が示されているのではないでしょうか?この言い方は完全に正確ではありません。フロントエンドにとっては、ウォレットの接続は確かに身分を証明できますが、バックエンドのサポートが必要なインターフェース呼び出しにおいては、アドレスを渡すだけでは身分を検証することはできません。なぜなら、アドレスは公開情報だからです。
! SIWEマニュアル:Dappをより強力にする方法は?
SIWEの原理とプロセス
SIWEのプロセスは、3つのステップに要約できます: ウォレットを接続 - サイン - 身分証明を取得。これらの3つのステップについて詳しく見てみましょう:
ウォレットを接続する
これは一般的なWeb3操作であり、ウォレットプラグインを通じてDappにユーザーのウォレットを接続できます。
サイン
SIWEの署名ステップには、Nonce値の取得、ウォレット署名、およびバックエンド署名検証が含まれます。
まず、バックエンドのインターフェースを呼び出してNonce値を取得する必要があります。バックエンドはランダムなNonceを生成し、現在のアドレスに関連付けて、後続の署名の準備をします。
フロントエンドがNonce値を取得した後、Nonce、ドメイン名、チェーンID、署名内容などを含む署名内容を構築します。そして、ウォレットが提供する署名メソッドを使用して内容に署名します。
最後に署名をバックエンドに送信して検証します。
ID を取得する
バックエンドが署名の検証に成功した後、対応するユーザー身分証明が返されます。通常はJWTトークンです。フロントエンドはその後のリクエストでアドレスと身分証明を持参することで、ウォレットの所有権を証明できます。
! SIWEマニュアル:Dappをより強力にする方法は?
SIWEの実践
私たちは実際の操作を通じてSIWE機能を実現できます。目的は、Dappがユーザーの身分証明のためにJWTを返すことです。注意が必要です。以下のデモは基本的なプロセスを示すためのものであり、本番環境ではセキュリティのリスクが存在する可能性があります。
###の準備
この記事では、Next.jsを使用してアプリケーションを開発するためにNode.js環境を準備する必要があります。Next.jsの利点は、フロントエンドとバックエンドを分割することなく、フルスタックプロジェクトを直接開発できることです。
依存関係をインストールする
まず、Next.jsをインストールします:
npx create-next-app@14
提示に従ってインストールを完了したら、プロジェクトディレクトリに入り、プロジェクトを起動します:
npm run dev
SIWEに関連する依存関係をインストールする
私たちは、ウォレット接続とSIWE機能を実現するためにAnt Design Web3コンポーネントライブラリを使用しています:
npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save
ワグミのご紹介
Ant Design Web3のSIWEはWagmiライブラリに依存しています。layout.tsxで関連するProviderを導入し、プロジェクト全体でWagmiが提供するHooksを使用できるようにします。
まず、WagmiProvider 構成を定義します。
JSXの "クライアントを使用する"; 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 siweconfig="{{" 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={クエリクライアント} > <jwtprovider.provider value="{jwt}">{children}</jwtprovider.provider> ); };
export default WagmiProvider;
! SIWEマニュアル:Dappをより強力にする方法は?
次に、ウォレット接続ボタンを追加します:
JSXの "クライアントを使用する"; 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}としてサインインします; };
リターン( <>
これで、私たちはシンプルなSIWEログインフレームワークを実現しました。
! 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、 }); }
メッセージを確認する
バックエンドは署名内容を検証し、後続の権限検証に使用するJWTを返す必要があります:
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などのノードサービスを使用して、対応するRPC接続を取得し、コード内のデフォルトRPCを置き換えてください。
JavaScriptの const publicClient = createPublicClient({ チェーン: メインネット, transport: http('), //ZAN ノードサービス RPC });
これにより、検証時間を大幅に短縮し、インターフェースの速度を向上させることができます。
! SIWEマニュアル:Dappをより強力にする方法は?
! SIWEマニュアル:Dappをより強力にする方法は?