SIWE: ¿Cómo implementar la identificación de Ethereum para mejorar las funciones de Dapp?
SIWE(Iniciar sesión con Ethereum) es un método para verificar la identificación del usuario en Ethereum, similar a iniciar una transacción de cartera, utilizado para demostrar el control del usuario sobre la cartera. El proceso de autenticación actual es muy simple, solo se necesita firmar la información en el complemento de la cartera, y la mayoría de los complementos de cartera comunes ya lo han soportado.
Este artículo discute principalmente los escenarios de firma en Ethereum, sin abordar otras cadenas públicas como Solana o SUI.
¿Cuándo se necesita usar SIWE?
Si tu Dapp tiene los siguientes requisitos, puedes considerar usar SIWE:
Tener su propio sistema de usuarios
Necesita consultar información relacionada con la privacidad del usuario
Pero si tu Dapp se centra principalmente en funciones de consulta, como aplicaciones similares a etherscan, entonces no necesariamente necesitas SIWE.
Es posible que te preguntes, ¿no se ha demostrado la propiedad de la billetera después de conectarse a la Dapp a través de la billetera? Esta afirmación es parcialmente correcta. Desde la perspectiva del frontend, la conexión de la billetera indica efectivamente la identificación, pero para las llamadas a la API que requieren soporte backend, simplemente pasar la dirección no es suficiente, ya que la dirección es información pública y cualquier persona puede "tomarla prestada".
El principio y el proceso de SIWE
El proceso de SIWE se puede resumir en tres pasos: conectar la billetera - firmar - obtener la identificación. Vamos a detallar estos tres pasos.
conectar billetera
Esta es una operación común de Web3, que conecta tu billetera en Dapp a través de un complemento de billetera.
firma
Los pasos de firma de SIWE incluyen obtener el valor de Nonce, la firma de la billetera y la verificación de la firma en el backend.
Primero es necesario llamar a la interfaz de backend para obtener el valor de Nonce. Después de recibir la solicitud, el backend generará un valor de Nonce aleatorio y lo asociará con la dirección actual, preparándose para la firma posterior.
Después de obtener el valor Nonce en el front-end, construir el contenido de la firma, incluyendo el valor Nonce, el dominio, el ID de la cadena, el contenido de la firma, etc., normalmente se utiliza el método de firma proporcionado por la billetera para firmar.
Una vez que se construya la firma, envíala al backend.
obtener identificación
Una vez que la validación de la firma en el backend se haya completado, se devolverá la identificación de usuario correspondiente, como JWT. Cuando el frontend envíe solicitudes al backend posteriormente, incluirá la dirección correspondiente y la identificación, lo que permitirá demostrar la propiedad de la billetera.
Práctica SIWE
Ahora hay muchos componentes y bibliotecas que apoyan la conexión rápida de billeteras y SIWE. Vamos a hacer una práctica, el objetivo es hacer que tu Dapp pueda devolver JWT para la identificación del usuario.
Atención, este ejemplo solo se utiliza para presentar el flujo básico de SIWE, su uso en un entorno de producción puede presentar problemas de seguridad.
trabajo preparatorio
Utilizamos Next.js para desarrollar aplicaciones, y necesitamos preparar el entorno de Node.js. La ventaja de usar Next.js es que se pueden desarrollar proyectos de pila completa directamente, sin necesidad de separar el front-end y el back-end.
instalar dependencias
Primero instala Next.js, ejecuta en el directorio del proyecto:
npx create-next-app@14
Una vez completada la instalación según las instrucciones, acceda al directorio del proyecto y inicie:
npm run dev
Luego visita localhost:3000 para ver el proyecto básico de Next.js en funcionamiento.
Instalar dependencias relacionadas con SIWE
Usamos Ant Design Web3 para implementar SIWE, porque es gratuito, se mantiene activamente, la experiencia de uso es similar a la de una biblioteca de componentes común y soporta SIWE.
La SIWE de Ant Design Web3 depende de la biblioteca Wagmi para su implementación. Importamos el Provider relacionado en layout.tsx, lo que permite que todo el proyecto utilice los Hooks proporcionados por Wagmi.
Primero, define la configuración de WagmiProvider:
javascript
"use client";
import { getNonce, verifyMessage } from "@/app/api";
import {
Mainnet,
MetaMask,
OkxWallet,
TokenPocket,
WagmiWeb3ConfigProvider,
WalletConnect,
} de "@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 = new QueryClient();
Utilizamos el Provider proporcionado por Ant Design Web3 y definimos algunas interfaces de SIWE, cuya implementación se presentará más adelante.
Luego, agrega un botón para conectar la billetera, como entrada de conexión frontal.
Hasta aquí, hemos integrado brevemente SIWE.
A continuación, define un botón de conexión para conectar la billetera y firmar:
javascript
"use client";
importar tipo { Cuenta } de "@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 function App() {
const jwt = React.useContext(JwtProvider);
Así hemos implementado un marco de inicio de sesión SIWE muy simple.
Implementación de la interfaz
SIWE necesita algunas interfaces para ayudar al backend a verificar la identificación del usuario. Ahora vamos a implementarlo de manera simple.
Nonce
Nonce se utiliza para que la billetera genere diferentes contenidos de firma cada vez que se firma, mejorando la fiabilidad. La generación del nonce necesita estar asociada con la dirección proporcionada por el usuario para mejorar la precisión de la verificación.
La implementación del nonce es bastante directa, primero se genera una cadena aleatoria ( compuesta por letras y números ), luego se establece una asociación entre el nonce y la dirección:
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");
if (!address) {
throw new Error("Dirección inválida");
}
const nonce = randomBytes(16).toString("hex");
addressMap.set(address, nonce);
return Response.json({
datos: nonce,
});
}
signMessage
signMessage se utiliza para firmar contenido, generalmente se completa a través de un complemento de billetera, normalmente solo necesitamos especificar el método. En este ejemplo se usa el método de firma de Wagmi.
verificarMensaje
Después de que el usuario firme, debe enviar el contenido anterior a la firma junto con la firma al backend para su verificación. El backend analiza el contenido de la firma para compararlo; si coincide, significa que la verificación ha sido exitosa.
Además, es necesario realizar una verificación de seguridad del contenido de la firma, como verificar si el valor de Nonce coincide con el asignado al usuario. Una vez verificado, se devuelve el JWT del usuario para la verificación de permisos posterior:
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"; // Por favor, utiliza una clave más segura y añade las correspondientes verificaciones de expiración, etc.
Hasta aquí, se ha desarrollado una Dapp que implementa básicamente el inicio de sesión SIWE.
Sugerencias de optimización
Al realizar el inicio de sesión con SIWE, si se utiliza el nodo RPC predeterminado, el proceso de verificación puede tardar hasta 30 segundos. Por lo tanto, se recomienda encarecidamente utilizar un servicio de nodo especializado para mejorar el tiempo de respuesta de la interfaz.
Después de obtener la conexión HTTPS RPC de la red principal de Ethereum, reemplace el RPC predeterminado de publicClient en el código:
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 me gusta
Recompensa
15
6
Compartir
Comentar
0/400
AirdropHustler
· hace19h
Hmm, esto todavía se considera mainstream, lo he estado usando desde hace tiempo.
Ver originalesResponder0
FallingLeaf
· hace19h
¿Firmar significa dar privacidad? Déjame pensarlo un momento.
Ver originalesResponder0
BearMarketMonk
· hace19h
¿Identificación? Solo otro truco más para tomar a la gente por tonta.
Ver originalesResponder0
MidnightSnapHunter
· hace19h
La firma no es más que un asunto de plugin.
Ver originalesResponder0
Degentleman
· hace19h
La función de SIWE ya debería haber llegado, ¿verdad?
Guía de implementación de SIWE: Mejora de la funcionalidad de verificación de identidad de Dapp
SIWE: ¿Cómo implementar la identificación de Ethereum para mejorar las funciones de Dapp?
SIWE(Iniciar sesión con Ethereum) es un método para verificar la identificación del usuario en Ethereum, similar a iniciar una transacción de cartera, utilizado para demostrar el control del usuario sobre la cartera. El proceso de autenticación actual es muy simple, solo se necesita firmar la información en el complemento de la cartera, y la mayoría de los complementos de cartera comunes ya lo han soportado.
Este artículo discute principalmente los escenarios de firma en Ethereum, sin abordar otras cadenas públicas como Solana o SUI.
¿Cuándo se necesita usar SIWE?
Si tu Dapp tiene los siguientes requisitos, puedes considerar usar SIWE:
Pero si tu Dapp se centra principalmente en funciones de consulta, como aplicaciones similares a etherscan, entonces no necesariamente necesitas SIWE.
Es posible que te preguntes, ¿no se ha demostrado la propiedad de la billetera después de conectarse a la Dapp a través de la billetera? Esta afirmación es parcialmente correcta. Desde la perspectiva del frontend, la conexión de la billetera indica efectivamente la identificación, pero para las llamadas a la API que requieren soporte backend, simplemente pasar la dirección no es suficiente, ya que la dirección es información pública y cualquier persona puede "tomarla prestada".
El principio y el proceso de SIWE
El proceso de SIWE se puede resumir en tres pasos: conectar la billetera - firmar - obtener la identificación. Vamos a detallar estos tres pasos.
conectar billetera
Esta es una operación común de Web3, que conecta tu billetera en Dapp a través de un complemento de billetera.
firma
Los pasos de firma de SIWE incluyen obtener el valor de Nonce, la firma de la billetera y la verificación de la firma en el backend.
Primero es necesario llamar a la interfaz de backend para obtener el valor de Nonce. Después de recibir la solicitud, el backend generará un valor de Nonce aleatorio y lo asociará con la dirección actual, preparándose para la firma posterior.
Después de obtener el valor Nonce en el front-end, construir el contenido de la firma, incluyendo el valor Nonce, el dominio, el ID de la cadena, el contenido de la firma, etc., normalmente se utiliza el método de firma proporcionado por la billetera para firmar.
Una vez que se construya la firma, envíala al backend.
obtener identificación
Una vez que la validación de la firma en el backend se haya completado, se devolverá la identificación de usuario correspondiente, como JWT. Cuando el frontend envíe solicitudes al backend posteriormente, incluirá la dirección correspondiente y la identificación, lo que permitirá demostrar la propiedad de la billetera.
Práctica SIWE
Ahora hay muchos componentes y bibliotecas que apoyan la conexión rápida de billeteras y SIWE. Vamos a hacer una práctica, el objetivo es hacer que tu Dapp pueda devolver JWT para la identificación del usuario.
Atención, este ejemplo solo se utiliza para presentar el flujo básico de SIWE, su uso en un entorno de producción puede presentar problemas de seguridad.
trabajo preparatorio
Utilizamos Next.js para desarrollar aplicaciones, y necesitamos preparar el entorno de Node.js. La ventaja de usar Next.js es que se pueden desarrollar proyectos de pila completa directamente, sin necesidad de separar el front-end y el back-end.
instalar dependencias
Primero instala Next.js, ejecuta en el directorio del proyecto:
npx create-next-app@14
Una vez completada la instalación según las instrucciones, acceda al directorio del proyecto y inicie:
npm run dev
Luego visita localhost:3000 para ver el proyecto básico de Next.js en funcionamiento.
Instalar dependencias relacionadas con SIWE
Usamos Ant Design Web3 para implementar SIWE, porque es gratuito, se mantiene activamente, la experiencia de uso es similar a la de una biblioteca de componentes común y soporta SIWE.
En la terminal, introduce:
npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save
introducir Wagmi
La SIWE de Ant Design Web3 depende de la biblioteca Wagmi para su implementación. Importamos el Provider relacionado en layout.tsx, lo que permite que todo el proyecto utilice los Hooks proporcionados por Wagmi.
Primero, define la configuración de WagmiProvider:
javascript "use client"; import { getNonce, verifyMessage } from "@/app/api"; import { Mainnet, MetaMask, OkxWallet, TokenPocket, WagmiWeb3ConfigProvider, WalletConnect, } de "@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 = new QueryClient();
const WagmiProvider: React.FC = ({ children }) => { const [jwt, setJwt] = React.useState(null);
return ( <wagmiweb3configprovider siwe="{{" getnonce:="" async="" (address)=""> (esperar obtenerNonce(dirección)).datos, createMessage: (props) => { return createSiweMessage({ ...props, statement: "Ant Design Web3" }); }, verifyMessage: async (message, signature) => { const jwt = (await verifyMessage(message, signature)).data; setJwt(jwt); return !!jwt; }, }} chains={[Mainnet]} transports={{ [Mainnet.id]: http(), }} walletConnect={{ projectId: YOUR_WALLET_CONNECT_PROJECT_ID, }} wallets={[} MetaMask(), WalletConnect(), TokenPocket({ grupo: "Popular", }), OkxWallet(), ]} queryClient={queryClient} > {children} ); };
export default WagmiProvider;
Utilizamos el Provider proporcionado por Ant Design Web3 y definimos algunas interfaces de SIWE, cuya implementación se presentará más adelante.
Luego, agrega un botón para conectar la billetera, como entrada de conexión frontal.
Hasta aquí, hemos integrado brevemente SIWE.
A continuación, define un botón de conexión para conectar la billetera y firmar:
javascript "use client"; importar tipo { Cuenta } de "@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 function App() { const jwt = React.useContext(JwtProvider);
const renderSignBtnText = ( defaultDom: React.ReactNode, cuenta?: Cuenta ) => { const { address } = account ?? {}; const ellipsisAddress = address ? ${address.slice(0, 6)}...${address.slice(-6)} : ""; regresar Iniciar sesión como ${ellipsisAddress}; };
return ( <> {(cuenta) => ( <connectbutton.signin accountcomponent="{false}" renderbuttontext="{(dom)" ==""> renderSignBtnText(dom, account)} /> )} <connectbutton.signin> {jwt} ); }
Así hemos implementado un marco de inicio de sesión SIWE muy simple.
Implementación de la interfaz
SIWE necesita algunas interfaces para ayudar al backend a verificar la identificación del usuario. Ahora vamos a implementarlo de manera simple.
Nonce
Nonce se utiliza para que la billetera genere diferentes contenidos de firma cada vez que se firma, mejorando la fiabilidad. La generación del nonce necesita estar asociada con la dirección proporcionada por el usuario para mejorar la precisión de la verificación.
La implementación del nonce es bastante directa, primero se genera una cadena aleatoria ( compuesta por letras y números ), luego se establece una asociación entre el nonce y la dirección:
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");
if (!address) { throw new Error("Dirección inválida"); } const nonce = randomBytes(16).toString("hex"); addressMap.set(address, nonce); return Response.json({ datos: nonce, }); }
signMessage
signMessage se utiliza para firmar contenido, generalmente se completa a través de un complemento de billetera, normalmente solo necesitamos especificar el método. En este ejemplo se usa el método de firma de Wagmi.
verificarMensaje
Después de que el usuario firme, debe enviar el contenido anterior a la firma junto con la firma al backend para su verificación. El backend analiza el contenido de la firma para compararlo; si coincide, significa que la verificación ha sido exitosa.
Además, es necesario realizar una verificación de seguridad del contenido de la firma, como verificar si el valor de Nonce coincide con el asignado al usuario. Una vez verificado, se devuelve el JWT del usuario para la verificación de permisos posterior:
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"; // Por favor, utiliza una clave más segura y añade las correspondientes verificaciones de expiración, etc.
const publicClient = createPublicClient({ cadena: mainnet, transporte: 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);
// Verificar si el valor del nonce es consistente if (!nonce || nonce !== addressMap.get(address)) { throw new Error("Invalid nonce"); }
// Verificar el contenido de la firma const valid = await publicClient.verifySiweMessage({ mensaje, dirección, firma, });
if (!valid) { throw new Error("Firma no válida"); }
// Generar jwt y devolver const token = jwt.sign({ address }, JWT_SECRET, { expiresIn: "1h" }); return Response.json({ datos: token, }); }
Hasta aquí, se ha desarrollado una Dapp que implementa básicamente el inicio de sesión SIWE.
Sugerencias de optimización
Al realizar el inicio de sesión con SIWE, si se utiliza el nodo RPC predeterminado, el proceso de verificación puede tardar hasta 30 segundos. Por lo tanto, se recomienda encarecidamente utilizar un servicio de nodo especializado para mejorar el tiempo de respuesta de la interfaz.
Después de obtener la conexión HTTPS RPC de la red principal de Ethereum, reemplace el RPC predeterminado de publicClient en el código:
javascript const publicClient = createPublicClient({ cadena: mainnet, transporte: http('), //servicio RPC del nodo obtenido });
Después de la sustitución, el tiempo de verificación puede reducirse significativamente y la velocidad de la interfaz mejora notablemente.