SIWE Technical Guide: Building an Ethereum Authentication System for Dapp

SIWE Technical Implementation Guide: Building a Robust Dapp Identification System

SIWE(Sign-In with Ethereum) is a way to verify user identification on Ethereum, similar to initiating a transaction, proving the user's control over the wallet. Currently, mainstream wallet plugins support this simple identification method, requiring only a signature in the plugin.

This article mainly discusses the signature scenarios on Ethereum and does not involve other public chains.

When to Use SIWE

If your Dapp has the following requirements, you may consider using SIWE:

  • Have an independent user system
  • Need to query information related to user privacy

For query-based applications, such as blockchain explorers similar to etherscan, SIWE may not be necessary.

Although it seems that the identification has been proven after connecting the wallet on the Dapp front end, it is not enough to only pass the address for API calls that require back-end support, because the address is public information and can be easily impersonated.

SIWE User Manual: How to Make Your Dapp More Powerful?

The Principle and Process of SIWE

The SIWE process can be summarized in three steps: connect the wallet, sign, and obtain identification.

Connect Wallet

This is a common Web3 operation, connecting a wallet in a Dapp through a wallet plugin.

signature

This includes three steps: obtaining the Nonce value, wallet signature, and backend signature verification.

  1. Retrieve the randomly generated Nonce value from the backend, associated with the current address.

  2. Construct the signature content on the front end, including Nonce value, domain name, chain ID, and other information, and sign it using the methods provided by the wallet.

  3. Send the signature to the backend for verification.

obtain identification

After the backend verification of the signature is successful, return the user identification ( like JWT ). The frontend subsequent requests should include the address and identification to prove wallet ownership.

SIWE User Manual: How to Make Your Dapp Stronger?

Practical Guide

The following will introduce how to implement SIWE functionality in a Nextjs project, returning a JWT for identification verification.

Environment Preparation

  1. Install Nextjs:

npx create-next-app@14

  1. Install SIWE-related dependencies:

npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save

SIWE User Manual: How to Make Your Dapp More Powerful?

Introduce Wagmi

Import WagmiProvider in layout.tsx:

javascript "use client"; import { getNonce, verifyMessage } from "@/app/api"; import { Mainnet, MetaMask, OkxWallet, TokenPocket, WagmiWeb3ConfigProvider, WalletConnect, ] from "@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(=""> )await getNonce(address().data, 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={)} transports={{ [Mainnet.id]: http[Mainnet](, }} walletConnect={{ projectId: YOUR_WALLET_CONNECT_PROJECT_ID, }} wallets={[} MetaMask)(, WalletConnect)(, TokenPocket){ group: "Popular", }(, OkxWallet)(, ]} queryClient={queryClient} > {children} ); };

export default WagmiProvider;

![SIWE User Manual: How to Make Your Dapp More Powerful?])https://img-cdn.gateio.im/webp-social/moments-53c03d1cb26f29a9d739e3d1aa0816df.webp(

) Add connection button

Add connect wallet and sign buttons in the component:

javascript "use client"; 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 function App###( { const jwt = React.useContext)JwtProvider(;

const renderSignBtnText = ) defaultDom: React.ReactNode, account?: Account ( => { const { address } = account ?? {}; const ellipsisAddress = address ? ${address.slice)0, 6(}...${address.slice)-6(} : ""; return Sign in as ${ellipsisAddress}; };

return ) <>

JWT: {jwt}
(; }

![SIWE User Manual: How to Make Your Dapp More Powerful?])https://img-cdn.gateio.im/webp-social/moments-18a98c883797c414a689c54ae0d65302.webp(

) interface implementation

Nonce interface

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)"Invalid address"(; } const nonce = randomBytes)16(.toString)("hex")(; addressMap.set)address, nonce(; return Response.json){ data: nonce, }(; }

)# Verification Signature Interface

javascript import { createPublicClient, http } from "viem"; import { mainnet } from "viem/chains"; import jwt from "jsonwebtoken"; import { parseSiweMessage } from "viem/siwe"; import { addressMap } from "../cache";

const JWT_SECRET = "your-secret-key";

const publicClient = createPublicClient###{ chain: mainnet, transport: http((, });

export async function POST)request: Request( { const { signature, message } = await request.json)(;

const { nonce, address = "0x" } = parseSiweMessage)message(;

if )!nonce || nonce !== addressMap.get(address() { throw new Error)"Invalid nonce"(; }

const valid = await publicClient.verifySiweMessage){ message, address, signature, }(;

if )!valid( { throw new Error)"Invalid signature"(; }

const token = jwt.sign){ address }, JWT_SECRET, { expiresIn: "1h" }(; return Response.json){ data: token, }(; }

![SIWE User Manual: How to Make Your Dapp Stronger?])https://img-cdn.gateio.im/webp-social/moments-9351d7f08e48962120d591c3a0c7d245.webp(

Optimization Suggestions

To improve the SIWE login speed, it is recommended to use dedicated node services. Taking the ZAN node service as an example, after obtaining the Ethereum mainnet HTTPS RPC connection, replace the default RPC of publicClient:

javascript const publicClient = createPublicClient){ chain: mainnet, transport: http('(, //ZAN node service RPC });

This can significantly reduce verification time and improve interface response speed.

![SIWE User Manual: How to Make Your Dapp More Powerful?])https://img-cdn.gateio.im/webp-social/moments-0ce46cff7473e96e768adfb5fc6dafb8.webp(

DAPP-5.68%
ETH8%
View Original
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.
  • Reward
  • 5
  • Repost
  • Share
Comment
0/400
MrRightClickvip
· 07-16 07:52
Just sign it, no need to make it so complicated.
View OriginalReply0
BearMarketSurvivorvip
· 07-16 03:02
This kind of high-end stuff again.
View OriginalReply0
SpeakWithHatOnvip
· 07-13 20:00
With this verification difficulty, even a trap can pass.
View OriginalReply0
NFTDreamervip
· 07-13 19:58
What's there to be tangled about? Just go for it.
View OriginalReply0
BlockTalkvip
· 07-13 19:57
Why is identification verification so troublesome?
View OriginalReply0
Trade Crypto Anywhere Anytime
qrCode
Scan to download Gate app
Community
English
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)