دليل تنفيذ تقنية SIWE: بناء نظام موثوق للتحقق من هوية Dapp
SIWE(تسجيل الدخول باستخدام إيثيريوم) هي وسيلة للتحقق من هوية المستخدم على شبكة إيثيريوم، مشابهة لإجراء المعاملات، لإثبات تحكم المستخدم في المحفظة. تدعم معظم ملحقات المحفظة الشائعة هذه الطريقة البسيطة للتحقق من الهوية، كل ما عليك هو التوقيع في الملحق.
تتناول هذه المقالة سيناريوهات التوقيع على إيثريوم، ولا تتعلق بسلاسل الكتل العامة الأخرى.
متى تحتاج لاستخدام SIWE
إذا كان لديك Dapp يتطلب ما يلي، يمكنك التفكير في استخدام SIWE:
وجود نظام مستخدمين مستقل
الحاجة إلى استفسار حول المعلومات المتعلقة بخصوصية المستخدم
بالنسبة للتطبيقات التي تركز على الاستعلام، مثل مستعرضات الكتل الشبيهة بـ etherscan، فلا داعي لاستخدام SIWE.
على الرغم من أنه يبدو أنه تم إثبات التعريف بالهوية بعد الاتصال بالمحفظة في واجهة Dapp، إلا أن مجرد تمرير العنوان غير كافٍ لاستدعاءات واجهة برمجة التطبيقات التي تحتاج إلى دعم من الخلفية، حيث أن العنوان هو معلومات عامة ويمكن أن يتم انتحالها.
مبدأ SIWE والعملية
يمكن تلخيص عملية SIWE في ثلاث خطوات: توصيل المحفظة، التوقيع، والحصول على التعريف بالهوية.
ربط المحفظة
هذه عملية شائعة في Web3، حيث يتم توصيل المحفظة في Dapp من خلال ملحق المحفظة.
توقيع
يشمل الحصول على قيمة Nonce، توقيع المحفظة، والتحقق من توقيع الخلفية في ثلاث خطوات:
الحصول على قيمة Nonce التي تم إنشاؤها عشوائيًا من الخلفية، وترتبط بالعناوين الحالية.
بناء محتوى التوقيع في الواجهة الأمامية، بما في ذلك قيمة Nonce، واسم النطاق، ومعرف السلسلة، وما إلى ذلك، باستخدام الطريقة التي توفرها المحفظة للتوقيع.
إرسال التوقيع إلى الواجهة الخلفية للتحقق.
الحصول على التعريف بالهوية
بعد التحقق من صحة التوقيع في الخلفية، يتم إرجاع هوية المستخدم ( مثل JWT). يجب أن تتضمن الطلبات اللاحقة من الواجهة الأمامية العنوان وهوية المستخدم، لإثبات ملكية المحفظة.
دليل الممارسة
سوف نقدم أدناه كيفية تنفيذ وظيفة SIWE في مشروع Nextjs، وإرجاع JWT للتحقق من الهوية.
جافا سكريبت
استيراد { randomBytes } من "التشفير" ؛
import { addressMap } من ".. /cache";
تصدير الدالة غير المتزامنة GET(request: Request) {
const { searchParams } = عنوان URL الجديد(request.url);
const address = searchParams.get( "address");
إذا (!address) {
throw new Error("عنوان غير صالح");
}
const nonce = randomBytes(16).toString("hex");
addressMap.set(العنوان, nonce);
إرجاع Response.json({
البيانات: nonce,
});
}
واجهة التحقق من التوقيع
جافاسكريبت
import { createPublicClient, http } من "viem";
استيراد { الشبكة الرئيسية } من "viem/chains";
استيراد jwt من "jsonwebtoken";
import { parseSiweMessage } من "viem / siwe" ؛
استيراد { addressMap } من "../cache";
const JWT_SECRET = "مفتاحك السري" ؛
const publicClient = createPublicClient({
السلسلة: الشبكة الرئيسية,
النقل: http(),
});
لزيادة سرعة تسجيل الدخول إلى SIWE، يُنصح باستخدام خدمات العقد المخصصة. على سبيل المثال، بعد الحصول على اتصال HTTPS RPC لشبكة Ethereum الرئيسية باستخدام خدمة عقد ZAN، استبدل RPC الافتراضي لـ publicClient:
قد تحتوي هذه الصفحة على محتوى من جهات خارجية، يتم تقديمه لأغراض إعلامية فقط (وليس كإقرارات/ضمانات)، ولا ينبغي اعتباره موافقة على آرائه من قبل Gate، ولا بمثابة نصيحة مالية أو مهنية. انظر إلى إخلاء المسؤولية للحصول على التفاصيل.
دليل تقنية SIWE: بناء نظام تحقق من الهوية على إثيريوم لتطبيقات Dapp
دليل تنفيذ تقنية SIWE: بناء نظام موثوق للتحقق من هوية Dapp
SIWE(تسجيل الدخول باستخدام إيثيريوم) هي وسيلة للتحقق من هوية المستخدم على شبكة إيثيريوم، مشابهة لإجراء المعاملات، لإثبات تحكم المستخدم في المحفظة. تدعم معظم ملحقات المحفظة الشائعة هذه الطريقة البسيطة للتحقق من الهوية، كل ما عليك هو التوقيع في الملحق.
تتناول هذه المقالة سيناريوهات التوقيع على إيثريوم، ولا تتعلق بسلاسل الكتل العامة الأخرى.
متى تحتاج لاستخدام SIWE
إذا كان لديك Dapp يتطلب ما يلي، يمكنك التفكير في استخدام SIWE:
بالنسبة للتطبيقات التي تركز على الاستعلام، مثل مستعرضات الكتل الشبيهة بـ etherscan، فلا داعي لاستخدام SIWE.
على الرغم من أنه يبدو أنه تم إثبات التعريف بالهوية بعد الاتصال بالمحفظة في واجهة Dapp، إلا أن مجرد تمرير العنوان غير كافٍ لاستدعاءات واجهة برمجة التطبيقات التي تحتاج إلى دعم من الخلفية، حيث أن العنوان هو معلومات عامة ويمكن أن يتم انتحالها.
مبدأ SIWE والعملية
يمكن تلخيص عملية SIWE في ثلاث خطوات: توصيل المحفظة، التوقيع، والحصول على التعريف بالهوية.
ربط المحفظة
هذه عملية شائعة في Web3، حيث يتم توصيل المحفظة في Dapp من خلال ملحق المحفظة.
توقيع
يشمل الحصول على قيمة Nonce، توقيع المحفظة، والتحقق من توقيع الخلفية في ثلاث خطوات:
الحصول على قيمة Nonce التي تم إنشاؤها عشوائيًا من الخلفية، وترتبط بالعناوين الحالية.
بناء محتوى التوقيع في الواجهة الأمامية، بما في ذلك قيمة Nonce، واسم النطاق، ومعرف السلسلة، وما إلى ذلك، باستخدام الطريقة التي توفرها المحفظة للتوقيع.
إرسال التوقيع إلى الواجهة الخلفية للتحقق.
الحصول على التعريف بالهوية
بعد التحقق من صحة التوقيع في الخلفية، يتم إرجاع هوية المستخدم ( مثل JWT). يجب أن تتضمن الطلبات اللاحقة من الواجهة الأمامية العنوان وهوية المستخدم، لإثبات ملكية المحفظة.
دليل الممارسة
سوف نقدم أدناه كيفية تنفيذ وظيفة SIWE في مشروع Nextjs، وإرجاع JWT للتحقق من الهوية.
إعداد البيئة
npx create-next-app@14
npm تثبيت antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save
إدخال Wagmi
قدم WagmiProvider في layout.tsx:
جافا سكريبت "استخدام العميل"؛ استيراد { الحصول على nonce, التحقق من الرسالة } من "@/app/api"; استيراد { الشبكة الرئيسية، ميتا ماسك, محفظة Okx, توكن بوكيت, WagmiWeb3ConfigProvider, WalletConnect، } من "@ant-design/web3-wagmi"; import { QueryClient } من "@tanstack/react-query" ؛ استيراد React من "react"; import { createSiweMessage } من "viem / siwe" ؛ استيراد { http } من "wagmi"؛ استيراد { JwtProvider } من "./JwtProvider" ؛
const YOUR_WALLET_CONNECT_PROJECT_ID = "c07c0051c2055890eade3556618e38a6"; const queryClient = QueryClient() جديد;
const WagmiProvider: React.FC = ({ children }) = > { const [jwt, setJwt] = React.useState(null);
( الإرجاع <wagmiweb3configprovider siwe="{{" getnonce:="" async="" (address)=""> (انتظر الحصول على nonce(عنوان)).بيانات, createMessage: (props) => { العودة createSiweMessage( { ... الدعائم ، بيان: "Ant Design Web3" }); }, verifyMessage: (message غير متزامن، signature) = > { const jwt = (await verifyMessage(message, signature)).data; setJwt(jwt). أعاد!! JWT. }, }} السلاسل = {[Mainnet]} transports={{ [Mainnet.id]: http()، }} walletConnect={{ معرف المشروع: YOUR_WALLET_CONNECT_PROJECT_ID ، }} المحافظ={[ MetaMask()، WalletConnect()، TokenPocket({ المجموعة: "شائع" ، }), OkxWallet()، ]} queryClient={queryClient} > {أطفال} ); };
تصدير WagmiProvider الافتراضي ؛
إضافة زر الاتصال
إضافة زر ربط المحفظة وزر التوقيع في المكون:
جافا سكريبت "استخدم العميل"; استيراد النوع { الحساب } من "@ant-design/web3"; استيراد { ConnectButton ، Connector } من "@ant-design / web3" ؛ import { Flex ، Space } من "antd" ؛ استيراد React من "react"; استيراد { JwtProvider } من "./JwtProvider" ؛
تصدير الدالة الافتراضية App() { const jwt = React.useContext(JwtProvider);
const renderSignBtnText = ( defaultDom: React.ReactNode ، الحساب؟: الحساب ) => { const { address } = حساب ؟؟ {}; const ellipsisAddress = العنوان ? ${address.slice(0, 6)}...${address.slice(-6)} : ""; العودة لتسجيل الدخول كـ ${ellipsisAddress}; };
( الإرجاع <> <flex vertical="" فجوة ="وسط">
تنفيذ الواجهة
واجهة Nonce
جافا سكريبت استيراد { randomBytes } من "التشفير" ؛ import { addressMap } من ".. /cache";
تصدير الدالة غير المتزامنة GET(request: Request) { const { searchParams } = عنوان URL الجديد(request.url); const address = searchParams.get( "address");
إذا (!address) { throw new Error("عنوان غير صالح"); } const nonce = randomBytes(16).toString("hex"); addressMap.set(العنوان, nonce); إرجاع Response.json({ البيانات: nonce, }); }
واجهة التحقق من التوقيع
جافاسكريبت import { createPublicClient, http } من "viem"; استيراد { الشبكة الرئيسية } من "viem/chains"; استيراد jwt من "jsonwebtoken"; import { parseSiweMessage } من "viem / siwe" ؛ استيراد { addressMap } من "../cache";
const JWT_SECRET = "مفتاحك السري" ؛
const publicClient = createPublicClient({ السلسلة: الشبكة الرئيسية, النقل: http(), });
تصدير الدالة غير المتزامنة POST(request: Request) { const { signature, message } = await request.json();
const { nonce ، العنوان = "0x" } = parseSiweMessage(message) ؛
إذا (!nonce || nonce !== addressMap.get(address)) { رمي Error( جديد "غير صالح") ؛ }
const valid = await publicClient.verifySiweMessage({ رسالة، العنوان، توقيع، });
إذا (!valid) { throw new Error("توقيع غير صالح"); }
رمز const = jwt.sign({ address }, JWT_SECRET, { expiresIn: "1h" }); إرجاع Response.json({ البيانات: رمز, }); }
اقتراحات تحسين
لزيادة سرعة تسجيل الدخول إلى SIWE، يُنصح باستخدام خدمات العقد المخصصة. على سبيل المثال، بعد الحصول على اتصال HTTPS RPC لشبكة Ethereum الرئيسية باستخدام خدمة عقد ZAN، استبدل RPC الافتراضي لـ publicClient:
جافا سكريبت const publicClient = createPublicClient({ السلسلة: الشبكة الرئيسية, النقل: http('), //خدمة RPC لعقد ZAN });
يمكن أن يقلل ذلك بشكل كبير من وقت التحقق، ويزيد من سرعة استجابة الواجهة.