Hướng dẫn thực hiện SIWE: Tăng cường chức năng xác thực danh tính Dapp

SIWE: Làm thế nào để thực hiện xác thực danh tính Ethereum để nâng cao chức năng Dapp

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

Bài viết này chủ yếu thảo luận về các tình huống chữ ký trên Ethereum, không đề cập đến các chuỗi công khai khác như Solana, SUI.

Khi nào cần sử dụng SIWE

Nếu Dapp của bạn có các yêu cầu sau, bạn có thể xem xét sử dụng SIWE:

  • Có hệ thống người dùng riêng
  • Cần tra cứu thông tin liên quan đến quyền riêng tư của người dùng

Nhưng nếu Dapp của bạn chủ yếu là chức năng truy vấn, chẳng hạn như ứng dụng giống etherscan, thì không nhất thiết phải cần SIWE.

Bạn có thể hỏi, sau khi kết nối ví trên Dapp, không phải đã chứng minh quyền sở hữu ví rồi sao? Câu nói này phần nào đúng. Đối với frontend, việc kết nối ví thực sự cho thấy danh tính, nhưng đối với các cuộc gọi API cần hỗ trợ backend, chỉ truyền địa chỉ là không đủ, vì địa chỉ là thông tin công khai, bất kỳ ai cũng có thể "mượn".

Nguyên lý và quy trình 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 - nhận danh tính. Hãy cùng tìm hiểu chi tiết về ba bước này.

kết nối ví

Đây là một thao tác Web3 phổ biến, kết nối ví của bạn trong Dapp thông qua plugin ví.

chữ ký

Các bước ký SIWE bao gồm lấy giá trị Nonce, ký ví và xác thực ký ở phía sau.

Đầu tiên cần gọi API backend để lấy giá trị Nonce. Sau khi backend nhận yêu cầu, nó sẽ tạo ra một giá trị Nonce ngẫu nhiên và liên kết với địa chỉ hiện tại, chuẩn bị cho việc ký sau này.

Sau khi lấy giá trị Nonce từ phía trước, xây dựng nội dung chữ ký, bao gồm giá trị Nonce, tên miền, ID chuỗi, nội dung chữ ký, thường sử dụng phương pháp ký do ví cung cấp.

Sau khi xây dựng xong chữ ký, hãy gửi nó cho backend.

lấy danh tính

Sau khi xác thực chữ ký ở phía backend thành công, sẽ trả về danh tính người dùng tương ứng, như JWT. Khi phía frontend gửi yêu cầu đến backend sau đó, cần đính kèm địa chỉ và danh tính tương ứng, để 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?

Thực hành SIWE

Hiện nay có nhiều thành phần và thư viện hỗ trợ kết nối ví nhanh chóng và SIWE. Chúng ta hãy thực hành một chút, mục tiêu là để Dapp của bạn có thể trả về JWT để xác thực danh tính người dùng.

Lưu ý, ví dụ này chỉ được sử dụng để giới thiệu quy trình cơ bản của SIWE, việc sử dụng trong môi trường sản xuất có thể gặp vấn đề về an toàn.

công việc chuẩn bị

Chúng tôi sử dụng Next.js để phát triển ứng dụng, cần chuẩn bị môi trường Node.js. Lợi ích của việc sử dụng Next.js là có thể phát triển dự án full-stack trực tiếp, không cần tách biệt frontend và backend.

cài đặt phụ thuộc

Đầu tiên cài đặt Next.js, chạy trong thư mục dự án:

npx create-next-app@14

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

npm run dev

Sau đó truy cập localhost:3000 để xem dự án Next.js cơ bản đã chạy.

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

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

Nhập vào terminal:

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

giới thiệu Wagmi

Ant Design Web3 của SIWE phụ thuộc vào thư viện Wagmi để thực hiện. Chúng tôi đã nhập các Provider liên quan trong layout.tsx, giúp toàn bộ dự án có thể sử dụng các Hooks do Wagmi cung cấp.

Đầu tiên định nghĩa cấu hình WagmiProvider:

javascript "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 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={[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;

Chúng tôi sử dụng Provider được cung cấp bởi Ant Design Web3, và định nghĩa một số giao diện của SIWE, cụ thể sẽ được giới thiệu ở phần sau.

Sau đó thêm nút kết nối ví, như một cổng kết nối phía trước.

Đến đây, chúng ta đã kết nối đơn giản với SIWE.

Tiếp theo định nghĩa một nút kết nối, thực hiện kết nối ví và ký kết:

javascript "use client"; import type { Account } from "@ant-design/web3"; import { ConnectButton, Connector } from "@ant-design/web3"; import { Flex, Space } from "antd"; import React từ "react"; import { JwtProvider } from "./JwtProvider";

xuất 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)} : ""; đăng nhập dưới danh tính ${ellipsisAddress}; };

return ( <> {(tài khoản) => ( <connectbutton.signin accountcomponent="{false}" renderbuttontext="{(dom)" ==""> renderSignBtnText(dom, account)} /> )} </connectbutton.signin> {jwt} ); }

Vậy là chúng ta đã xây dựng được một khung đăng nhập SIWE đơn giản nhất.

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

SIWE cần một số giao diện để giúp backend xác thực danh tính người dùng. Bây giờ chúng ta hãy triển khai một cách đơn giản.

Nonce

Nonce được sử dụng để giúp ví tạo ra nội dung chữ ký khác nhau mỗi khi ký, nhằm nâng cao độ tin cậy. Việc tạo ra Nonce cần phải liên kết với địa chỉ do người dùng cung cấp, nhằm tăng cường độ chính xác trong xác thực.

Việc thực hiện Nonce rất đơn giản, đầu tiên tạo một chuỗi ngẫu nhiên ( bao gồm chữ cái và số ), sau đó thiết lập mối liên hệ giữa nonce và address:

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");

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({ dữ liệu: nonce, }); }

signMessage

signMessage được sử dụng để ký nội dung, thường được thực hiện thông qua plugin ví, chúng tôi chỉ cần chỉ định phương pháp. Trong ví dụ này, phương pháp ký của Wagmi được sử dụng.

xác thực tin nhắn

Sau khi người dùng ký, cần gửi nội dung trước khi ký và chữ ký đến phía backend để xác thực. Phía backend sẽ phân tích nội dung từ chữ ký để so sánh, nếu一致 thì có nghĩa là xác thực thành công.

Ngoài ra, cần thực hiện kiểm tra tính bảo mật của nội dung chữ ký, chẳng hạn như xác nhận giá trị Nonce có khớp với giá trị được phân bổ cho người dùng hay không. Sau khi xác nhận thành công, trả về JWT của người dùng để sử dụng cho việc kiểm tra quyền hạn sau này:

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"; // Vui lòng sử dụng khóa an toàn hơn và thêm kiểm tra hết hạn tương ứng.

const publicClient = createPublicClient({ chuỗi: mainnet, transport: http(), });

export async function POST(request: Request) { const { chữ ký, thông điệp } = await yêu cầu.json();

const { nonce, address = "0x" } = parseSiweMessage(message); console.log("nonce", nonce, address, addressMap);

// Kiểm tra xem giá trị nonce có一致 không nếu (!nonce || nonce !== addressMap.get(address)) { throw new Error("Invalid nonce"); }

// Kiểm tra nội dung chữ ký const valid = await publicClient.verifySiweMessage({ thông điệp, địa chỉ, chữ ký, });

nếu (!valid) { throw new Error("Invalid signature"); }

// Tạo jwt và trả về const token = jwt.sign({ address }, JWT_SECRET, { expiresIn: "1h" }); return Response.json({ dữ liệu: token, }); }

Đến đây, một Dapp cơ bản thực hiện đăng nhập SIWE đã hoàn thành.

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?

Đề xuất tối ưu

Khi thực hiện đăng nhập SIWE, nếu sử dụng nút RPC mặc định, quá trình xác thực có thể mất tới 30 giây. Do đó, rất khuyến khích sử dụng dịch vụ nút chuyên dụng để cải thiện thời gian phản hồi của giao diện.

Sau khi có được kết nối HTTPS RPC đến mạng chính của Ethereum, hãy thay thế RPC mặc định của publicClient trong mã.

javascript const publicClient = createPublicClient({ chuỗi: mainnet, transport: http('), // dịch vụ RPC của nút đã nhận được });

Sau khi thay thế, thời gian xác minh có thể giảm đáng kể, tốc độ giao diện rõ rệt được cải thiệ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?

Xem bản gốc
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.
  • Phần thưởng
  • 6
  • Chia sẻ
Bình luận
0/400
AirdropHustlervip
· 19giờ trước
Ừm, cái này cũng xem như là mainstream, ông đã dùng từ sớm.
Xem bản gốcTrả lời0
FallingLeafvip
· 19giờ trước
Ký tên thì phải cho riêng tư? Để tôi suy nghĩ thêm.
Xem bản gốcTrả lời0
BearMarketMonkvip
· 19giờ trước
danh tính xác thực? Chỉ là một trò mới để chơi đùa với mọi người nữa thôi.
Xem bản gốcTrả lời0
MidnightSnapHuntervip
· 19giờ trước
Chữ ký không phải chỉ là một việc của plugin sao?
Xem bản gốcTrả lời0
Degentlemanvip
· 19giờ trước
Chức năng SIWE này lẽ ra đã phải có từ lâu rồi.
Xem bản gốcTrả lời0
GateUser-75ee51e7vip
· 19giờ trước
Chữ ký ví tiền thông thường là đủ rồi
Xem bản gốcTrả lời0
  • 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)