# SIWE:Dappsの機能を改善するためのキーテクノロジーSIWE(イーサリアムでのサインイン)は、ユーザーの身元をイーサリアム上で検証する方法であり、ウォレット取引を発起するのに似ていて、ユーザーがウォレットを制御していることを証明します。現在の認証方法は非常にシンプルで、ウォレットプラグインで情報に署名するだけで済み、ほとんどの一般的なウォレットプラグインがサポートしています。この記事では、Ethereum上の署名シナリオについて主に議論し、SolanaやSUIなどの他のブロックチェーンには言及しません。## SIWEは必要ですかもしあなたの Dapp が以下の要件を持っているなら、SIWE の使用を検討してください:- 自分のユーザーシステムを持つ- ユーザーのプライバシーに関連する情報を確認する必要がありますただし、あなたのDappが主にクエリ機能を持っている場合、例えばetherscanのようなアプリケーションの場合、SIWEを使用する必要はありません。あなたは疑問に思うかもしれませんが、Dappでウォレット接続を通じて、すでにウォレットの所有権が証明されているのではないでしょうか?この言い方は部分的に正しいです。フロントエンドにとって、ウォレットの接続は確かにアイデンティティを示しますが、バックエンドのサポートが必要なインターフェース呼び出しにおいて、アドレスを渡すだけでは不十分です。なぜなら、アドレスは公開情報であり、誰でも"借用"することができるからです。## SIWEの原理とプロセスSIWEプロセスは、3つのステップに要約できます: ウォレットを接続する - 署名する - 身分識別を取得する。これらの3つのステップについて詳しく見ていきましょう。### ウォレットを接続するウォレットを接続することは一般的なWeb3操作であり、ウォレットプラグインを介してDappにウォレットを接続できます。### サインSIWEの署名手順には、Nonce値の取得、ウォレット署名、バックエンド署名の検証が含まれます。Nonce 値を取得するには、バックエンドインターフェースを呼び出す必要があります。バックエンドがリクエストを受け取ると、ランダムな Nonce 値を生成し、現在のアドレスに関連付けて、後続の署名の準備を行います。フロントエンドがNonce値を取得した後、Nonce値、ドメイン名、チェーンID、署名内容などを含む署名内容を構築する必要があります。通常、ウォレットが提供する署名方法を使用して署名します。署名を構築したら、それをバックエンドに送信します。### ID を取得するバックエンドで署名が検証されると、ユーザーのIDが返されます。例えば、JWTです。フロントエンドのその後のリクエストでは、該当するアドレスとIDを持参し、ウォレットの所有権を証明できます。! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-9e9c9e786391f84b004cd8450a29acce)## 練習現在、多くのコンポーネントとライブラリがウォレット接続とSIWEへの迅速なアクセスをサポートしています。我々の目標は、Dappがユーザー認証のためにJWTを返すことができるようにすることです。注意してください、このデモはSIWEの基本的なプロセスを紹介するためのものであり、製品環境での使用にはセキュリティ上の問題がある可能性があります。###の準備この記事では、Next.jsを使用してアプリケーションを開発します。Node.js環境が必要です。Next.jsの利点は、フルスタックプロジェクトを直接開発でき、フロントエンドとバックエンドの2つのプロジェクトに分ける必要がないことです。### 依存関係をインストールするまず Next.js をインストールし、プロジェクトディレクトリで実行します:npx create-next-app@14指示に従ってインストールが完了したら、プロジェクトディレクトリに入り、実行します:npm run dev端末の指示に従って、localhost:3000 にアクセスすると、基本的な Next.js プロジェクトを見ることができます。### SIWE 関連の依存関係をインストールするSIWE はログインシステムを必要とするため、ウォレットを接続する必要があります。ここでは、Ant Design Web3 を使用します。理由は:1. 完全無料かつ積極的に維持されている2. Web3コンポーネントライブラリとして、使用体験は通常のコンポーネントライブラリに似ており、追加の精神的負担はありません。3. SIWEをサポート端末で実行する: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 構成を定義します。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 siweconfig="{{" getnonce:="" async="" (address)=""> (nonceを取得するために待機(アドレス)).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()、 トークンポケット({ グループ: "人気", }), OkxWallet()、 ]} queryClient={クエリクライアント} > {子供} </wagmiweb3configprovider> );};export default WagmiProvider;そして、ウォレット接続ボタンを追加します。これで、フロントエンドに接続の入り口が追加されました。これでSIWEが接続され、手順は非常に簡単です。次に接続ボタンを定義し、ウォレットを接続して署名を実行します: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}としてサインインするを返す; }; リターン( <> <flex vertical="" gap="大きい"> <space> <connectbutton> </connectbutton></space> <div>{JWTの}</div> </flex> <!----> );}これで最も簡単なSIWEログインフレームワークが実現しました。! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-138fc08a9148099755d1fe162292922f)### インターフェース実装SIWEは、バックエンドがユーザーの身元を検証するのに役立ついくつかのインターフェースを必要としています。今、簡単に実装してみましょう。#### ノンスNonceは、ウォレットが毎回署名する際に生成される内容を変更し、署名の信頼性を向上させるために使用されます。Nonceの生成は、ユーザーが提供するアドレスに関連付ける必要があり、検証の正確性を高めます。Nonceの実装は非常に直接的です。まず、ランダムな文字列(を生成します。これはアルファベットと数字で構成されています)。その後、nonceとaddressを結びつけます:JavaScriptのimport { randomBytes } from "crypto";import { addressMap } from ".. /cache";非同期関数をエクスポートする GET(request: リクエスト) { const { searchParams } = 新しいURL(request.url); constアドレス= searchParams.get("アドレス"); if (!address) { 新しいError("無効なアドレス")をスローします。 } const nonce = randomBytes(16).toString("hex"); addressMap.set(住所、nonce); 戻り値 Response.json({ データ:nonce、 });}#### メッセージに署名signMessageは内容に署名するために使用され、この機能は通常ウォレットプラグインによって実行されるため、一般的には設定する必要はなく、メソッドを指定するだけで済みます。このデモではWagmiの署名メソッドを使用しています。#### メッセージを検証するユーザーが署名した後、署名前の内容と署名を一緒にバックエンドに送信する必要があります。バックエンドは署名から対応する内容を解析して比較し、一致すれば検証が通過したことを示します。さらに、署名内容のセキュリティチェックが必要であり、署名内容内の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 = "your-secret-key"; // より安全なキーを使用し、対応する期限チェックなどを追加してくださいconst publicClient = createPublicClient({チェーン: メインネット, トランスポート:http()、});export async 関数 POST(request: Request) { const {署名、メッセージ} = await request.json(); const { nonce, アドレス = "0x" } = parseSiweMessage(message); console.log("nonce", nonce, address, addressMap);// nonce 値が一致するかどうかを検証する if (!nonce || nonce !== addressMap.get(アドレス)) { 新しいError("無効なナンス")をスローします。 } 署名の内容を確認する const valid = await publicClient.verifySiweMessage({ メッセージ、 アドレス、 署名 }); if (!valid) { 新しいError("無効な署名")をスローします。 } // jwt を生成して返す const token = jwt.sign({ アドレス }, JWT_SECRET, { expiresIn: "1h" }); 戻り値 Response.json({ データ: トークン, });}これで、基本的なSIWEログインを実装したDappが完成しました。! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-355ea961b315585f7d217cbcf6a3fa69)## 最適化の提案SIWE ログイン認証のためにデフォルトの RPC ノードを使用する場合、約 30 秒かかる可能性があるため、インターフェースの応答時間を向上させるために専用ノードサービスの使用を強く推奨します。本記事では ZAN のノードサービスを使用しており、対応する RPC 接続は ZAN ノードサービスコンソールから取得できます。EthereumメインネットのHTTPS RPC接続を取得した後、コード内でpublicClientのデフォルトRPCを置き換えます:JavaScriptのconst publicClient = createPublicClient({チェーン: メインネット, transport: http('), //ZANノードサービスRPCを取得});交換後、検証時間は大幅に短縮され、インターフェースの速度が明らかに向上します。! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-53c03d1cb26f29a9d739e3d1aa0816df)! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-18a98c883797c414a689c54ae0d65302)! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-9351d7f08e48962120d591c3a0c7d245)! [SIWEマニュアル:Dappをより強力にする方法は? ](https://img-cdn.gateio.im/social/moments-0ce46cff7473e96e768adfb5fc6dafb8)
SIWEテクノロジーは、Dappsのユーザー認証を向上させるのに役立ちます
SIWE:Dappsの機能を改善するためのキーテクノロジー
SIWE(イーサリアムでのサインイン)は、ユーザーの身元をイーサリアム上で検証する方法であり、ウォレット取引を発起するのに似ていて、ユーザーがウォレットを制御していることを証明します。現在の認証方法は非常にシンプルで、ウォレットプラグインで情報に署名するだけで済み、ほとんどの一般的なウォレットプラグインがサポートしています。
この記事では、Ethereum上の署名シナリオについて主に議論し、SolanaやSUIなどの他のブロックチェーンには言及しません。
SIWEは必要ですか
もしあなたの Dapp が以下の要件を持っているなら、SIWE の使用を検討してください:
ただし、あなたのDappが主にクエリ機能を持っている場合、例えばetherscanのようなアプリケーションの場合、SIWEを使用する必要はありません。
あなたは疑問に思うかもしれませんが、Dappでウォレット接続を通じて、すでにウォレットの所有権が証明されているのではないでしょうか?この言い方は部分的に正しいです。フロントエンドにとって、ウォレットの接続は確かにアイデンティティを示しますが、バックエンドのサポートが必要なインターフェース呼び出しにおいて、アドレスを渡すだけでは不十分です。なぜなら、アドレスは公開情報であり、誰でも"借用"することができるからです。
SIWEの原理とプロセス
SIWEプロセスは、3つのステップに要約できます: ウォレットを接続する - 署名する - 身分識別を取得する。これらの3つのステップについて詳しく見ていきましょう。
ウォレットを接続する
ウォレットを接続することは一般的なWeb3操作であり、ウォレットプラグインを介してDappにウォレットを接続できます。
サイン
SIWEの署名手順には、Nonce値の取得、ウォレット署名、バックエンド署名の検証が含まれます。
Nonce 値を取得するには、バックエンドインターフェースを呼び出す必要があります。バックエンドがリクエストを受け取ると、ランダムな Nonce 値を生成し、現在のアドレスに関連付けて、後続の署名の準備を行います。
フロントエンドがNonce値を取得した後、Nonce値、ドメイン名、チェーンID、署名内容などを含む署名内容を構築する必要があります。通常、ウォレットが提供する署名方法を使用して署名します。
署名を構築したら、それをバックエンドに送信します。
ID を取得する
バックエンドで署名が検証されると、ユーザーのIDが返されます。例えば、JWTです。フロントエンドのその後のリクエストでは、該当するアドレスとIDを持参し、ウォレットの所有権を証明できます。
! SIWEマニュアル:Dappをより強力にする方法は?
練習
現在、多くのコンポーネントとライブラリがウォレット接続とSIWEへの迅速なアクセスをサポートしています。我々の目標は、Dappがユーザー認証のためにJWTを返すことができるようにすることです。注意してください、このデモはSIWEの基本的なプロセスを紹介するためのものであり、製品環境での使用にはセキュリティ上の問題がある可能性があります。
###の準備
この記事では、Next.jsを使用してアプリケーションを開発します。Node.js環境が必要です。Next.jsの利点は、フルスタックプロジェクトを直接開発でき、フロントエンドとバックエンドの2つのプロジェクトに分ける必要がないことです。
依存関係をインストールする
まず Next.js をインストールし、プロジェクトディレクトリで実行します:
npx create-next-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
ワグミのご紹介
Ant Design Web3のSIWEはWagmiライブラリに依存しています。layout.tsxに関連するProviderをインポートして、プロジェクト全体でWagmiが提供するHooksを使用できるようにする必要があります。
まず、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 siweconfig="{{" getnonce:="" async="" (address)=""> (nonceを取得するために待機(アドレス)).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()、 トークンポケット({ グループ: "人気", }), OkxWallet()、 ]} queryClient={クエリクライアント} > {子供} ); };
export default WagmiProvider;
そして、ウォレット接続ボタンを追加します。これで、フロントエンドに接続の入り口が追加されました。これでSIWEが接続され、手順は非常に簡単です。
次に接続ボタンを定義し、ウォレットを接続して署名を実行します:
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}としてサインインするを返す; };
リターン( <>
これで最も簡単なSIWEログインフレームワークが実現しました。
! SIWEマニュアル:Dappをより強力にする方法は?
インターフェース実装
SIWEは、バックエンドがユーザーの身元を検証するのに役立ついくつかのインターフェースを必要としています。今、簡単に実装してみましょう。
ノンス
Nonceは、ウォレットが毎回署名する際に生成される内容を変更し、署名の信頼性を向上させるために使用されます。Nonceの生成は、ユーザーが提供するアドレスに関連付ける必要があり、検証の正確性を高めます。
Nonceの実装は非常に直接的です。まず、ランダムな文字列(を生成します。これはアルファベットと数字で構成されています)。その後、nonceとaddressを結びつけます:
JavaScriptの import { randomBytes } from "crypto"; import { addressMap } from ".. /cache";
非同期関数をエクスポートする GET(request: リクエスト) { const { searchParams } = 新しいURL(request.url); constアドレス= searchParams.get("アドレス");
if (!address) { 新しいError("無効なアドレス")をスローします。 } const nonce = randomBytes(16).toString("hex"); addressMap.set(住所、nonce); 戻り値 Response.json({ データ:nonce、 }); }
メッセージに署名
signMessageは内容に署名するために使用され、この機能は通常ウォレットプラグインによって実行されるため、一般的には設定する必要はなく、メソッドを指定するだけで済みます。このデモではWagmiの署名メソッドを使用しています。
メッセージを検証する
ユーザーが署名した後、署名前の内容と署名を一緒にバックエンドに送信する必要があります。バックエンドは署名から対応する内容を解析して比較し、一致すれば検証が通過したことを示します。
さらに、署名内容のセキュリティチェックが必要であり、署名内容内の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 = "your-secret-key"; // より安全なキーを使用し、対応する期限チェックなどを追加してください
const publicClient = createPublicClient({ チェーン: メインネット, トランスポート:http()、 });
export async 関数 POST(request: Request) { const {署名、メッセージ} = await request.json();
const { nonce, アドレス = "0x" } = parseSiweMessage(message); console.log("nonce", nonce, address, addressMap);
// nonce 値が一致するかどうかを検証する if (!nonce || nonce !== addressMap.get(アドレス)) { 新しいError("無効なナンス")をスローします。 }
署名の内容を確認する const valid = await publicClient.verifySiweMessage({ メッセージ、 アドレス、 署名 });
if (!valid) { 新しいError("無効な署名")をスローします。 }
// jwt を生成して返す const token = jwt.sign({ アドレス }, JWT_SECRET, { expiresIn: "1h" }); 戻り値 Response.json({ データ: トークン, }); }
これで、基本的なSIWEログインを実装したDappが完成しました。
! SIWEマニュアル:Dappをより強力にする方法は?
最適化の提案
SIWE ログイン認証のためにデフォルトの RPC ノードを使用する場合、約 30 秒かかる可能性があるため、インターフェースの応答時間を向上させるために専用ノードサービスの使用を強く推奨します。本記事では ZAN のノードサービスを使用しており、対応する RPC 接続は ZAN ノードサービスコンソールから取得できます。
EthereumメインネットのHTTPS RPC接続を取得した後、コード内でpublicClientのデフォルトRPCを置き換えます:
JavaScriptの const publicClient = createPublicClient({ チェーン: メインネット, transport: http('), //ZANノードサービスRPCを取得 });
交換後、検証時間は大幅に短縮され、インターフェースの速度が明らかに向上します。
! SIWEマニュアル:Dappをより強力にする方法は?
! SIWEマニュアル:Dappをより強力にする方法は?
! SIWEマニュアル:Dappをより強力にする方法は?
! SIWEマニュアル:Dappをより強力にする方法は?