Lựa chọn mới cho xác thực danh tính Ethereum: Giải thích chi tiết SIWE và hướng dẫn thực chiến

Hướng dẫn thực hiện xác thực danh tính Ethereum: SIWE

SIWE(Đăng Nhập với Ethereum) là một phương thức xác thực danh tính người dùng dựa trên Ethereum, tương tự như việc ví khởi tạo giao dịch, được sử dụng để chứng minh quyền kiểm soát của người dùng đối với ví cụ thể. Hiện nay, các plugin ví phổ biến đã hỗ trợ phương thức xác thực đơn giản này, chỉ cần ký thông tin trong plugin.

Bài viết này sẽ tập trung vào việc triển khai SIWE trên Ethereum, không đề cập đến các chuỗi công khai khác như Solana, SUI.

Tình huống sử dụng SIWE

Nếu ứng dụng phi tập trung của bạn (Dapp) có các yêu cầu sau, bạn có thể xem xét việc sử dụng SIWE:

  • Có hệ thống người dùng độc lập
  • Cần truy vấn thông tin liên quan đến danh tính người dùng

Đối với các ứng dụng chủ yếu là tra cứu ( như trình duyệt blockchain ), thì có thể không sử dụng SIWE.

Mặc dù việc kết nối qua ví trong Dapp có thể thể hiện danh tính, nhưng điều này chỉ có hiệu lực đối với frontend. Đối với các cuộc gọi API cần hỗ trợ backend, chỉ việc truyền thông tin địa chỉ là không đủ để chứng minh danh tính, vì địa chỉ là thông tin công khai.

Nguyên lý hoạt động của SIWE

Quy trình SIWE có thể được tóm tắt thành ba bước: kết nối ví, ký tên, lấy danh tính.

kết nối ví

Đây là thao tác Web3 phổ biến, kết nối ví của người dùng trong Dapp thông qua plugin ví.

chữ ký

Các bước ký bao gồm lấy giá trị Nonce, ký ví và xác minh chữ ký từ backend.

Phía sau tạo ra giá trị Nonce ngẫu nhiên và liên kết với địa chỉ, chuẩn bị cho quá trình ký tiếp theo. Phía trước nhận giá trị Nonce sau đó xây dựng nội dung ký, bao gồm giá trị Nonce, tên miền, ID chuỗi và các thông tin khác, sử dụng phương pháp do ví cung cấp để ký. Cuối cùng, gửi chữ ký đến phía sau để xác thực.

Lấy danh tính

Sau khi xác minh chữ ký ở phía backend thành công, trả về danh tính người dùng ( như JWT ). Khi thực hiện các yêu cầu tiếp theo từ phía frontend, mang theo địa chỉ và danh tính, có thể chứng minh quyền sở hữu ví.

Hướng dẫn sử dụng SIWE: Làm thế nào để làm cho Dapp của bạn mạnh mẽ hơn?

Ví dụ về triển khai SIWE

Dưới đây sẽ trình bày cách thực hiện chức năng SIWE trong dự án Nextjs, giúp Dapp có thể trả về JWT để xác thực danh tính người dùng.

Chuẩn bị môi trường

Ví dụ này được phát triển dựa trên Nextjs, cần chuẩn bị môi trường Node.js. Sử dụng Nextjs giúp phát triển dự án full-stack một cách thuận tiện, không cần tách biệt front-end và back-end.

Cài đặt phụ thuộc

Đầu tiên cài đặt Nextjs:

npx create-next-app@14

Sau khi hoàn thành cài đặt theo hướng dẫn, vào thư mục dự án và khởi động:

npm run dev

Truy cập localhost:3000 để xem dự án Nextjs cơ bản.

Cài đặt các phụ thuộc liên quan đến SIWE

Chúng tôi sẽ sử dụng Ant Design Web3 để thực hiện kết nối ví, nó miễn phí, được duy trì liên tục, và trải nghiệm sử dụng tương tự như thư viện thành phần thông thường, hỗ trợ chức năng SIWE.

Cài đặt các phụ thuộc liên quan:

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

cấu hình Wagmi

Trong layout.tsx, nhập WagmiProvider:

typescript “use client”; import { getNonce, verifyMessage } from “@/app/api”; import { Mainnet, MetaMask, OkxWallet, TokenPocket, WagmiWeb3ConfigProvider, WalletConnect, } từ “@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 siweconfig=“{{” 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={[Mainnet]} transports={{ [Mainnet.id]: http(), }} walletConnect={{ projectId: YOUR_WALLET_CONNECT_PROJECT_ID, }} ví={[ MetaMask(), WalletConnect(), TokenPocket({ nhóm: “Phổ biến”, }), OkxWallet(), ]} queryClient={queryClient} > {children} </wagmiweb3configprovider> ); };

xuất khẩu mặc định WagmiProvider;

Hướng dẫn sử dụng SIWE: Làm thế nào để biến Dapp của bạn trở nên mạnh mẽ hơn?

thực hiện nút kết nối

Thêm nút kết nối ví và ký.

typescript “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”;

xuất khẩu mặc định chức năng App() { const jwt = React.useContext(JwtProvider);

const renderSignBtnText = ( defaultDom: React.ReactNode, tài khoản?: Tài khoản ) => { const { address } = account ?? {}; const ellipsisAddress = address ? ${address.slice(0, 6)}…${address.slice(-6)} : “”; trở lại Đăng nhập với ${ellipsisAddress}; };

return ( <> <flex vertical=“” gap=“middle”> <space> <connectbutton> <connector.siwebutton renderbuttontext=“{renderSignBtnText}”> </connector.siwebutton></connectbutton></space> <div>JWT: {jwt}</div> </flex> <!----> ); }

SIWE hướng dẫn sử dụng: Làm thế nào để làm cho Dapp của bạn mạnh mẽ hơn?

triển khai giao diện backend

Giao diện Nonce

Tạo nonce ngẫu nhiên và liên kết với địa chỉ:

typescript 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”);

nếu (!address) { throw new Error(“Địa chỉ không hợp lệ”); } const nonce = randomBytes(16).toString(“hex”); addressMap.set(address, nonce); return Response.json({ data: nonce, }); }

Giao diện xác thực tin nhắn

Xác thực chữ ký và trả về JWT:

typescript import { createPublicClient, http } from “viem”; import { mainnet } from “viem/chains”; import jwt từ “jsonwebtoken”; import { parseSiweMessage } from “viem/siwe”; import { addressMap } from “…/cache”;

const JWT_SECRET = “your-secret-key”;

const publicClient = createPublicClient({ chuỗi: mainnet, vận chuyển: http(), });

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

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

nếu (!nonce || nonce !== addressMap.get(address)) { throw new Error(“Invalid nonce”); }

const valid = await publicClient.verifySiweMessage({ thông điệp, địa chỉ, chữ ký, });

nếu (!valid) { throw new Error(“Chữ ký không hợp lệ”); }

const token = jwt.sign({ address }, JWT_SECRET, { expiresIn: “1h” }); return Response.json({ dữ liệu: token, }); }

Hướng dẫn sử dụng SIWE: Làm thế nào để làm cho Dapp của bạn mạnh mẽ hơn?

Tối ưu hiệu suất

Để nâng cao tốc độ xác thực, nên sử dụng dịch vụ nút chuyên dụng. Lấy dịch vụ nút ZAN làm ví dụ, sau khi nhận được kết nối HTTPS RPC của mạng chính Ethereum, hãy thay thế RPC mặc định của publicClient:

typescript const publicClient = createPublicClient({ chuỗi: mainnet, vận chuyển: http('), //Dịch vụ RPC nút ZAN });

Điều này có thể giảm đáng kể thời gian xác thực, cải thiện tốc độ phản hồi của giao diện.

Hướng dẫn sử dụng SIWE: Làm thế nào để làm cho Dapp của bạn mạnh mẽ hơn?

SIWE hướng dẫn sử dụng: Làm thế nào để làm cho Dapp của bạn mạnh mẽ hơn?

SIWE sử dụng hướng dẫn: Làm thế nào để làm cho Dapp của bạn mạnh mẽ hơn?

ETH2.41%
Xem bản gốc
Trang này có thể chứa nội dung của bên thứ ba, được cung cấp chỉ nhằm mục đích thông tin (không phải là tuyên bố/bảo đảm) và không được coi là sự chứng thực cho quan điểm của Gate hoặc là lời khuyên về tài chính hoặc chuyên môn. Xem Tuyên bố từ chối trách nhiệm để biết chi tiết.
  • Phần thưởng
  • 7
  • Đăng lại
  • Retweed
Bình luận
0/400
Không có bình luận
  • Ghim
Giao dịch tiền điện tử mọi lúc mọi nơi
qrCode
Quét để tải xuống ứng dụng Gate
Cộng đồng
Tiếng Việt
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)