SIWE : la technologie clé pour améliorer les fonctionnalités des Dapps
SIWE (Sign-In with Ethereum) est une méthode de vérification de l'identité des utilisateurs sur Ethereum, similaire à l'initiation d'une transaction de portefeuille, prouvant que l'utilisateur a le contrôle du portefeuille. La méthode d'authentification actuelle est très simple, il suffit de signer les informations dans le plugin de portefeuille, et la plupart des plugins de portefeuille courants sont déjà pris en charge.
Cet article discute principalement des scénarios de signature sur Ethereum, sans aborder d'autres blockchains telles que Solana, SUI, etc.
Avez-vous besoin de SIWE
Si votre Dapp a les exigences suivantes, vous pouvez envisager d'utiliser SIWE :
Avoir son propre système d'utilisateurs
Besoin de consulter des informations liées à la confidentialité des utilisateurs
Mais si votre Dapp est principalement une fonctionnalité de requête, comme une application similaire à etherscan, vous pouvez ne pas utiliser SIWE.
Vous pourriez vous demander, après avoir connecté votre portefeuille sur Dapp, cela ne prouve-t-il pas déjà la propriété du portefeuille ? Cette affirmation est partiellement correcte. Du point de vue du frontend, la connexion du portefeuille indique effectivement l'identité, mais pour les appels d'interface nécessitant un support backend, transmettre uniquement l'adresse n'est pas suffisant, car l'adresse est une information publique, que n'importe qui peut "emprunter".
Principe et processus de SIWE
Le processus SIWE peut être résumé en trois étapes : connexion du portefeuille - signature - obtention de l'identifiant. Examinons ces trois étapes en détail.
Connecter le portefeuille
Connecter un portefeuille est une opération courante dans Web3, et il est possible de connecter un portefeuille dans une Dapp via un plugin de portefeuille.
signature
Les étapes de signature dans SIWE incluent l'obtention de la valeur Nonce, la signature du portefeuille et la vérification de la signature par le backend.
Pour obtenir la valeur Nonce, il est nécessaire d'appeler l'interface backend. Une fois la demande reçue, le backend générera une valeur Nonce aléatoire et l'associera à l'adresse actuelle, afin de préparer la signature ultérieure.
Après avoir obtenu la valeur Nonce côté frontend, il est nécessaire de construire le contenu de la signature, y compris la valeur Nonce, le nom de domaine, l'ID de chaîne, le contenu de la signature, etc. Cela se fait généralement en utilisant la méthode de signature fournie par le portefeuille.
Après avoir construit la signature, envoyez-la au backend.
Obtenir l'identifiant
Une fois que la vérification de la signature côté serveur est réussie, un identifiant d'utilisateur sera renvoyé, tel que JWT. Lors des requêtes ultérieures du côté client, il suffit d'inclure l'adresse correspondante et l'identifiant d'utilisateur pour prouver la propriété du portefeuille.
Pratique
Il existe de nombreux composants et bibliothèques qui prennent en charge une connexion rapide au portefeuille et à SIWE. Notre objectif est de permettre à Dapp de renvoyer un JWT pour la vérification de l'identité de l'utilisateur. Notez que cette démo est uniquement destinée à introduire le processus de base de SIWE, son utilisation en environnement de production peut présenter des problèmes de sécurité.
travaux préparatoires
Cet article utilise Next.js pour développer des applications, nécessitant un environnement Node.js. L'avantage de Next.js est qu'il permet de développer directement des projets full-stack, sans avoir à les diviser en deux projets distincts pour le front-end et le back-end.
Installer les dépendances
Tout d'abord, installez Next.js, exécutez dans le répertoire du projet :
npx create-next-app@14
Une fois l'installation terminée selon les instructions, entrez dans le répertoire du projet et exécutez :
npm run dev
Selon l'invite du terminal, vous pouvez accéder à localhost:3000 pour voir le projet de base Next.js.
Installer les dépendances liées à SIWE
SIWE nécessite un système de connexion, c'est pourquoi il est nécessaire de connecter un portefeuille. Ici, nous utilisons Ant Design Web3, car :
Entièrement gratuit et activement maintenu
En tant que bibliothèque de composants Web3, l'expérience utilisateur est similaire à celle d'une bibliothèque de composants ordinaire, sans charge mentale supplémentaire.
Ant Design Web3 dépend de la bibliothèque Wagmi pour SIWE. Nous devons importer le Provider pertinent dans layout.tsx afin que l'ensemble du projet puisse utiliser les Hooks fournis par Wagmi.
Tout d'abord, définissez la configuration de WagmiProvider :
javascript
"use client";
import { getNonce, verifyMessage } from "@/app/api";
importer {
Mainnet,
MetaMask,
OkxWallet,
TokenPocket,
WagmiWeb3ConfigProvider,
WalletConnect,
} de "@ant-design/web3-wagmi";
import { QueryClient } from "@tanstack/react-query";
importer React de "react";
import { createSiweMessage } from "viem/siwe";
import { http } from "wagmi";
import { JwtProvider } from "./JwtProvider";
const YOUR_WALLET_CONNECT_PROJECT_ID = "c07c0051c2055890eade3556618e38a6";
const queryClient = new QueryClient();
Ensuite, ajoutez le bouton de connexion du portefeuille, ce qui ajoute un point d'entrée de connexion sur le front-end. À ce stade, SIWE est déjà intégré, et les étapes sont très simples.
Ensuite, définissez le bouton de connexion pour connecter le portefeuille et signer :
javascript
"utiliser le client";
importer type { Account } from "@ant-design/web3";
import { ConnectButton, Connector } from "@ant-design/web3";
importer { Flex, Espace } de "antd";
importer React de "react";
import { JwtProvider } from "./JwtProvider";
export default function App() {
const jwt = React.useContext(JwtProvider);
const renderSignBtnText = (
defaultDom: React.ReactNode,
compte?: Compte
) => {
const { address } = account ?? {};
const ellipsisAddress = address
? ${address.slice(0, 6)}...${address.slice(-6)}
: "";
retournez Connectez-vous en tant que ${ellipsisAddress};
};
retourner (
<>
{jwt}
);
}
Cela a permis de réaliser un cadre de connexion SIWE très simple.
implémentation de l'interface
SIWE a besoin de certaines interfaces pour aider le backend à vérifier l'identité des utilisateurs. Maintenant, nous allons en réaliser une simple.
Nonce
Le Nonce est utilisé pour faire varier le contenu généré par le portefeuille à chaque signature, améliorant ainsi la fiabilité de la signature. La génération du Nonce doit être associée à l'adresse fournie par l'utilisateur, afin d'améliorer l'exactitude de la vérification.
La mise en œuvre du Nonce est très directe. Tout d'abord, générez une chaîne aléatoire ( composée de lettres et de chiffres ), puis établissez un lien entre le nonce et l'adresse :
javascript
import { randomBytes } from "crypto";
import { addressMap } from "../cache";
export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
const address = searchParams.get("address");
signMessage est utilisé pour signer le contenu, cette fonctionnalité est généralement réalisée par un plugin de portefeuille, nous n'avons généralement pas besoin de la configurer, il suffit de spécifier la méthode. Dans cette démo, nous utilisons la méthode de signature de Wagmi.
vérifierMessage
Après que l'utilisateur ait signé, il doit envoyer le contenu avant la signature et la signature elle-même au backend pour vérification. Le backend extrait le contenu correspondant de la signature pour comparaison; si cela correspond, cela signifie que la validation est réussie.
De plus, il est nécessaire de vérifier la sécurité du contenu de la signature, par exemple si la valeur Nonce dans le contenu de la signature correspond à celle qui a été délivrée à l'utilisateur, etc. Une fois la validation effectuée, il faut renvoyer le JWT de l'utilisateur pour la vérification des autorisations ultérieures, le code d'exemple est le suivant :
javascript
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
import jwt de "jsonwebtoken";
import { parseSiweMessage } from "viem/siwe";
import { addressMap } from "../cache";
const JWT_SECRET = "your-secret-key"; // Veuillez utiliser une clé plus sécurisée et ajouter une vérification d'expiration correspondante, etc.
// Vérifier si la valeur du nonce est cohérente
si (!nonce || nonce !== addressMap.get(address)) {
throw new Error("Nonce invalide");
}
// Vérifier le contenu de la signature
const valid = await publicClient.verifySiweMessage({
message,
adresse,
signature,
});
si (!valid) {
throw new Error("Signature invalide");
}
// Générer un jwt et le retourner
const token = jwt.sign({ address }, JWT_SECRET, { expiresIn: "1h" });
return Response.json({
données : jeton,
});
}
À ce stade, une Dapp de base implémentant la connexion SIWE est développée.
Suggestions d'optimisation
L'utilisation du nœud RPC par défaut pour l'authentification SIWE peut prendre près de 30 secondes, il est donc fortement recommandé d'utiliser un service de nœud dédié pour améliorer le temps de réponse de l'interface. Cet article utilise le service de nœud ZAN, et vous pouvez obtenir la connexion RPC correspondante à partir de la console de service de nœud ZAN.
Après avoir obtenu la connexion HTTPS RPC du réseau principal Ethereum, remplacez le RPC par défaut de publicClient dans le code :
javascript
const publicClient = createPublicClient({
chaîne : mainnet,
transport : http('), // Service RPC du nœud ZAN obtenu
});
Après le remplacement, le temps de validation sera considérablement réduit et la vitesse de l'interface sera nettement améliorée.
Cette page peut inclure du contenu de tiers fourni à des fins d'information uniquement. Gate ne garantit ni l'exactitude ni la validité de ces contenus, n’endosse pas les opinions exprimées, et ne fournit aucun conseil financier ou professionnel à travers ces informations. Voir la section Avertissement pour plus de détails.
22 J'aime
Récompense
22
8
Partager
Commentaire
0/400
MeltdownSurvivalist
· 07-13 16:09
La vérification de la sécurité est très importante.
Voir l'originalRépondre0
ForumMiningMaster
· 07-13 16:08
La vérification des signatures doit être effectuée en toute sécurité.
Voir l'originalRépondre0
GateUser-cff9c776
· 07-10 16:45
La signature est trop basique.
Voir l'originalRépondre0
BoredStaker
· 07-10 16:41
Cette technologie mérite d'être étudiée en profondeur.
Voir l'originalRépondre0
MEV_Whisperer
· 07-10 16:40
La sécurité de l'information est la plus importante.
La technologie SIWE aide les Dapps à améliorer l'identification des utilisateurs.
SIWE : la technologie clé pour améliorer les fonctionnalités des Dapps
SIWE (Sign-In with Ethereum) est une méthode de vérification de l'identité des utilisateurs sur Ethereum, similaire à l'initiation d'une transaction de portefeuille, prouvant que l'utilisateur a le contrôle du portefeuille. La méthode d'authentification actuelle est très simple, il suffit de signer les informations dans le plugin de portefeuille, et la plupart des plugins de portefeuille courants sont déjà pris en charge.
Cet article discute principalement des scénarios de signature sur Ethereum, sans aborder d'autres blockchains telles que Solana, SUI, etc.
Avez-vous besoin de SIWE
Si votre Dapp a les exigences suivantes, vous pouvez envisager d'utiliser SIWE :
Mais si votre Dapp est principalement une fonctionnalité de requête, comme une application similaire à etherscan, vous pouvez ne pas utiliser SIWE.
Vous pourriez vous demander, après avoir connecté votre portefeuille sur Dapp, cela ne prouve-t-il pas déjà la propriété du portefeuille ? Cette affirmation est partiellement correcte. Du point de vue du frontend, la connexion du portefeuille indique effectivement l'identité, mais pour les appels d'interface nécessitant un support backend, transmettre uniquement l'adresse n'est pas suffisant, car l'adresse est une information publique, que n'importe qui peut "emprunter".
Principe et processus de SIWE
Le processus SIWE peut être résumé en trois étapes : connexion du portefeuille - signature - obtention de l'identifiant. Examinons ces trois étapes en détail.
Connecter le portefeuille
Connecter un portefeuille est une opération courante dans Web3, et il est possible de connecter un portefeuille dans une Dapp via un plugin de portefeuille.
signature
Les étapes de signature dans SIWE incluent l'obtention de la valeur Nonce, la signature du portefeuille et la vérification de la signature par le backend.
Pour obtenir la valeur Nonce, il est nécessaire d'appeler l'interface backend. Une fois la demande reçue, le backend générera une valeur Nonce aléatoire et l'associera à l'adresse actuelle, afin de préparer la signature ultérieure.
Après avoir obtenu la valeur Nonce côté frontend, il est nécessaire de construire le contenu de la signature, y compris la valeur Nonce, le nom de domaine, l'ID de chaîne, le contenu de la signature, etc. Cela se fait généralement en utilisant la méthode de signature fournie par le portefeuille.
Après avoir construit la signature, envoyez-la au backend.
Obtenir l'identifiant
Une fois que la vérification de la signature côté serveur est réussie, un identifiant d'utilisateur sera renvoyé, tel que JWT. Lors des requêtes ultérieures du côté client, il suffit d'inclure l'adresse correspondante et l'identifiant d'utilisateur pour prouver la propriété du portefeuille.
Pratique
Il existe de nombreux composants et bibliothèques qui prennent en charge une connexion rapide au portefeuille et à SIWE. Notre objectif est de permettre à Dapp de renvoyer un JWT pour la vérification de l'identité de l'utilisateur. Notez que cette démo est uniquement destinée à introduire le processus de base de SIWE, son utilisation en environnement de production peut présenter des problèmes de sécurité.
travaux préparatoires
Cet article utilise Next.js pour développer des applications, nécessitant un environnement Node.js. L'avantage de Next.js est qu'il permet de développer directement des projets full-stack, sans avoir à les diviser en deux projets distincts pour le front-end et le back-end.
Installer les dépendances
Tout d'abord, installez Next.js, exécutez dans le répertoire du projet :
npx create-next-app@14
Une fois l'installation terminée selon les instructions, entrez dans le répertoire du projet et exécutez :
npm run dev
Selon l'invite du terminal, vous pouvez accéder à localhost:3000 pour voir le projet de base Next.js.
Installer les dépendances liées à SIWE
SIWE nécessite un système de connexion, c'est pourquoi il est nécessaire de connecter un portefeuille. Ici, nous utilisons Ant Design Web3, car :
Exécutez dans le terminal :
npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save
Introduire Wagmi
Ant Design Web3 dépend de la bibliothèque Wagmi pour SIWE. Nous devons importer le Provider pertinent dans layout.tsx afin que l'ensemble du projet puisse utiliser les Hooks fournis par Wagmi.
Tout d'abord, définissez la configuration de WagmiProvider :
javascript "use client"; import { getNonce, verifyMessage } from "@/app/api"; importer { Mainnet, MetaMask, OkxWallet, TokenPocket, WagmiWeb3ConfigProvider, WalletConnect, } de "@ant-design/web3-wagmi"; import { QueryClient } from "@tanstack/react-query"; importer React de "react"; import { createSiweMessage } from "viem/siwe"; import { http } from "wagmi"; import { JwtProvider } from "./JwtProvider";
const YOUR_WALLET_CONNECT_PROJECT_ID = "c07c0051c2055890eade3556618e38a6"; const queryClient = new QueryClient();
const WagmiProvider: React.FC = ({ children }) => { const [jwt, setJwt] = React.useState(null);
retourner ( <wagmiweb3configprovider siweconfig="{{" getnonce:="" async="" (address)="">
); };
export default WagmiProvider;
Ensuite, ajoutez le bouton de connexion du portefeuille, ce qui ajoute un point d'entrée de connexion sur le front-end. À ce stade, SIWE est déjà intégré, et les étapes sont très simples.
Ensuite, définissez le bouton de connexion pour connecter le portefeuille et signer :
javascript "utiliser le client"; importer type { Account } from "@ant-design/web3"; import { ConnectButton, Connector } from "@ant-design/web3"; importer { Flex, Espace } de "antd"; importer React de "react"; import { JwtProvider } from "./JwtProvider";
export default function App() { const jwt = React.useContext(JwtProvider);
const renderSignBtnText = ( defaultDom: React.ReactNode, compte?: Compte ) => { const { address } = account ?? {}; const ellipsisAddress = address ? ${address.slice(0, 6)}...${address.slice(-6)} : ""; retournez Connectez-vous en tant que ${ellipsisAddress}; };
retourner ( <>
Cela a permis de réaliser un cadre de connexion SIWE très simple.
implémentation de l'interface
SIWE a besoin de certaines interfaces pour aider le backend à vérifier l'identité des utilisateurs. Maintenant, nous allons en réaliser une simple.
Nonce
Le Nonce est utilisé pour faire varier le contenu généré par le portefeuille à chaque signature, améliorant ainsi la fiabilité de la signature. La génération du Nonce doit être associée à l'adresse fournie par l'utilisateur, afin d'améliorer l'exactitude de la vérification.
La mise en œuvre du Nonce est très directe. Tout d'abord, générez une chaîne aléatoire ( composée de lettres et de chiffres ), puis établissez un lien entre le nonce et l'adresse :
javascript import { randomBytes } from "crypto"; import { addressMap } from "../cache";
export async function GET(request: Request) { const { searchParams } = new URL(request.url); const address = searchParams.get("address");
si (!adresse) { throw new Error("Adresse invalide"); } const nonce = randomBytes(16).toString("hex"); addressMap.set(adresse, nonce); return Response.json({ données : nonce, }); }
signerMessage
signMessage est utilisé pour signer le contenu, cette fonctionnalité est généralement réalisée par un plugin de portefeuille, nous n'avons généralement pas besoin de la configurer, il suffit de spécifier la méthode. Dans cette démo, nous utilisons la méthode de signature de Wagmi.
vérifierMessage
Après que l'utilisateur ait signé, il doit envoyer le contenu avant la signature et la signature elle-même au backend pour vérification. Le backend extrait le contenu correspondant de la signature pour comparaison; si cela correspond, cela signifie que la validation est réussie.
De plus, il est nécessaire de vérifier la sécurité du contenu de la signature, par exemple si la valeur Nonce dans le contenu de la signature correspond à celle qui a été délivrée à l'utilisateur, etc. Une fois la validation effectuée, il faut renvoyer le JWT de l'utilisateur pour la vérification des autorisations ultérieures, le code d'exemple est le suivant :
javascript import { createPublicClient, http } from "viem"; import { mainnet } from "viem/chains"; import jwt de "jsonwebtoken"; import { parseSiweMessage } from "viem/siwe"; import { addressMap } from "../cache";
const JWT_SECRET = "your-secret-key"; // Veuillez utiliser une clé plus sécurisée et ajouter une vérification d'expiration correspondante, etc.
const publicClient = createPublicClient({ chaîne : mainnet, transport : http(), });
export async function POST(request: Request) { const { signature, message } = await request.json();
const { nonce, address = "0x" } = parseSiweMessage(message); console.log("nonce", nonce, address, addressMap);
// Vérifier si la valeur du nonce est cohérente si (!nonce || nonce !== addressMap.get(address)) { throw new Error("Nonce invalide"); }
// Vérifier le contenu de la signature const valid = await publicClient.verifySiweMessage({ message, adresse, signature, });
si (!valid) { throw new Error("Signature invalide"); }
// Générer un jwt et le retourner const token = jwt.sign({ address }, JWT_SECRET, { expiresIn: "1h" }); return Response.json({ données : jeton, }); }
À ce stade, une Dapp de base implémentant la connexion SIWE est développée.
Suggestions d'optimisation
L'utilisation du nœud RPC par défaut pour l'authentification SIWE peut prendre près de 30 secondes, il est donc fortement recommandé d'utiliser un service de nœud dédié pour améliorer le temps de réponse de l'interface. Cet article utilise le service de nœud ZAN, et vous pouvez obtenir la connexion RPC correspondante à partir de la console de service de nœud ZAN.
Après avoir obtenu la connexion HTTPS RPC du réseau principal Ethereum, remplacez le RPC par défaut de publicClient dans le code :
javascript const publicClient = createPublicClient({ chaîne : mainnet, transport : http('), // Service RPC du nœud ZAN obtenu });
Après le remplacement, le temps de validation sera considérablement réduit et la vitesse de l'interface sera nettement améliorée.