本範例提供了一個逐步指南,說明如何使用 DID Connect 實作一個基本的使用者登入系統。目標是使用者的 DID 錢包來驗證使用者,並檢索其基本個人資料,例如姓名和電子郵件地址。這是該程式庫最常見的用途之一。
我們將使用 WalletHandlers 與 Express.js 伺服器整合,並向使用者請求 profile 聲明。
運作方式
登入過程遵循標準的 DID Connect 工作流程:
初始化
後端使用應用程式的身份設定一個
WalletAuthenticator,並使用一個WalletHandlers實例來管理會話。處理器附加
一個特定的處理器被附加到一個 Express 路由(例如
/api/did/login)。此處理器定義了要請求的資訊(聲明)以及在成功驗證後執行的邏輯(onAuth)。使用者互動
前端顯示一個 DID Connect 按鈕或 QR code,與後端啟動會話。
錢包批准
使用者使用其 DID 錢包掃描 QR code,檢視請求(分享其個人資料)並批准。
後端回呼
伺服器上的
onAuth回呼被觸發,接收使用者的 DID(userDid)及其個人資料。建立會話
應用程式現在可以使用這些資訊來建立使用者會話、發行 token 或將使用者個人資料儲存到資料庫。
實作
以下是如何建立一個簡單的登入端點。
步驟 1:初始化 Authenticator 和 Handlers
首先,您需要使用您的應用程式詳細資訊設定 WalletAuthenticator,並使用 WalletHandlers 來管理會話狀態。
簡易登入設定
const express = require('express');
const { fromRandom } = require('@ocap/wallet');
const { WalletAuthenticator, WalletHandlers } = require('@arcblock/did-connect-js');
const SimpleStorage = require('@arcblock/did-connect-storage-nedb');
// 1. 為應用程式建立一個錢包
const wallet = fromRandom();
// 2. 使用應用程式和鏈資訊設定 authenticator
const authenticator = new WalletAuthenticator({
wallet,
baseUrl: 'http://localhost:3000', // 您的應用程式的基礎 URL
appInfo: {
name: 'Simple Login Example',
description: 'A simple example to demonstrate DID Connect login',
icon: '/images/logo.png', // 您的應用程式圖示的 URL
},
chainInfo: {
host: 'https://beta.abtnetwork.io/api',
id: 'beta',
},
});
// 3. 使用 authenticator 和儲存適配器初始化 handlers
const handlers = new WalletHandlers({
authenticator,
tokenStorage: new SimpleStorage({ dbPath: '/tmp/did_connect_login_example.db' }),
});
// 4. 建立一個 Express 應用程式
const app = express();
// 如果您的應用程式位於代理之後,這對於動態 baseUrl 推斷是必需的
app.set('trust proxy', true);WalletAuthenticator:此物件持有您的應用程式身份(錢包)和將在使用者錢包中顯示給使用者的元資料(appInfo、chainInfo)。WalletHandlers:此類別協調 DID Connect 會話。它需要一個authenticator和一個tokenStorage適配器來持久化會話狀態。did-connect-storage-nedb是一個簡單的基於檔案的儲存,適用於範例。
步驟 2:附加登入處理器
接下來,使用 handlers.attach() 方法建立 API 端點並定義您的登入流程的邏輯。此方法會自動為您建立像 /api/did/login/token 和 /api/did/login/status 這樣的路由。
附加登入處理器
handlers.attach(app, {
// DID Connect 端點的基礎路徑
// 例如,/api/did/login, /api/did/profile
action: 'login',
// 定義要從使用者錢包請求的聲明
claims: {
profile: () => ({
fields: ['fullName', 'email'],
description: '請提供您的姓名和電子郵件以登入。',
}),
},
// 成功驗證後執行的回呼函式
onAuth: async ({ userDid, claims }) => {
// userDid:已驗證使用者的 DID。
// claims:使用者提交的聲明陣列。
try {
const profile = claims.find((x) => x.type === 'profile');
console.log('登入成功!', { userDid, profile });
// 在實際應用程式中,您通常會:
// 1. 使用 userDid 在您的資料庫中尋找或建立使用者。
// 2. 儲存個人資料。
// 3. 為使用者建立會話或發行 JWT。
} catch (err) {
console.error('onAuth 回呼中發生錯誤', err);
}
},
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`伺服器正在 http://localhost:${PORT} 上執行`);
console.log(`DID Connect 登入端點已在 /api/did/login 準備就緒`);
});action: 'login':這會將生成的端點的基礎路徑設定為/api/did/login。claims.profile:此物件指定我們正在請求一個profile聲明。fields陣列列出了我們需要的具體資訊片段,而description則會顯示在使用者的錢包中,以解釋為什麼需要這些資訊。onAuth:這是最關鍵的部分。此函式僅在使用者成功驗證並批准請求後執行。它接收userDid和claims資料。在這裡,我們只是記錄資訊,但在實際應用程式中,這將是您處理使用者會話管理的地方。
執行此伺服器後,您可以使用 DID Connect UX 程式庫整合前端,將其指向 /api/did/login 端點以啟動登入流程。
後續步驟
現在您已經有了一個基本的登入系統,您可以探索更多進階功能: