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:

  • 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.

Manual de uso de SIWE: ¿Cómo hacer que tu Dapp sea más potente?

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.

Manual de uso de SIWE: ¿Cómo hacer que tu Dapp sea más potente?

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.

Manual de uso de SIWE: ¿Cómo hacer que tu Dapp sea más poderosa?

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.

Manual de uso de SIWE: ¿Cómo hacer que tu Dapp sea más poderosa?

Ver originales
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.
  • Recompensa
  • 6
  • Compartir
Comentar
0/400
AirdropHustlervip
· hace19h
Hmm, esto todavía se considera mainstream, lo he estado usando desde hace tiempo.
Ver originalesResponder0
FallingLeafvip
· hace19h
¿Firmar significa dar privacidad? Déjame pensarlo un momento.
Ver originalesResponder0
BearMarketMonkvip
· hace19h
¿Identificación? Solo otro truco más para tomar a la gente por tonta.
Ver originalesResponder0
MidnightSnapHuntervip
· hace19h
La firma no es más que un asunto de plugin.
Ver originalesResponder0
Degentlemanvip
· hace19h
La función de SIWE ya debería haber llegado, ¿verdad?
Ver originalesResponder0
GateUser-75ee51e7vip
· hace19h
Una firma de billetera normal es suficiente.
Ver originalesResponder0
  • Anclado
Opere con criptomonedas en cualquier momento y lugar
qrCode
Escanee para descargar la aplicación Gate
Comunidad
Español
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)