WalletHandlers 類別是一個高階實用工具,旨在將 DID Connect 工作流程無縫整合到 Express.js 或類似的伺服器端框架中。它會自動為給定的操作設定所有必要的 API 端點,處理您的應用程式和使用者 DID 錢包之間的通訊。
它與 WalletAuthenticator 協同工作,後者管理訊息的加密簽章和驗證。由於 WalletHandlers 是基於 Node.js 的 EventEmitter 建立的,因此您可以在權杖儲存中的會話狀態改變時,監聽各種生命週期事件。
建構函式
建立 DID Connect 處理程式的實例。此實例會協調處理 DID Connect 流程的 HTTP 請求。
DID Connect 處理程式設定
const { WalletHandlers } = require('@did-connect/handler');
const { WalletAuthenticator } = require('@did-connect/authenticator');
const { FileStorage } = require('@did-connect/storage-file');
// 1. 使用您應用程式的錢包和資訊初始化驗證器
const authenticator = new WalletAuthenticator({ wallet, appInfo, chainInfo });
// 2. 初始化一個儲存適配器來管理會話狀態
const tokenStorage = new FileStorage({ dbPath: './sessions.json' });
// 3. 建立處理程式實例
const handlers = new WalletHandlers({
authenticator,
tokenStorage,
});參數
- config
object(required) — WalletHandlers 實例的設定物件。- authenticator
WalletAuthenticator(required) — 負責加密操作的WalletAuthenticator實例。 - tokenStorage
object(required) — 處理會話狀態的權杖儲存實例(例如FileStorage、MongoStorage)。 - pathTransformer
function— 一個可選函式,用於轉換錢包回呼的 URL 路徑名稱,在代理或複雜的路由情境中很有用。 - onConnect
function— 一個可選的全域回呼函式,在錢包掃描 QR code 後、驗證請求發送前執行。它可用於全域權限檢查。拋出錯誤以中止流程。 - options
object— 一個可選物件,用於自訂處理程式的行為。- prefix
string(default:/api/did) — 所有產生的端點的 URL 前綴。 - cleanupDelay
number(default:60000) — 從儲存中清除已完成的會話前等待的時間(毫秒)。 - tokenKey
string(default:_t_) — 會話權杖的查詢參數鍵。 - encKey
string(default:_ek_) — 加密金鑰的查詢參數鍵。 - versionKey
string(default:_v_) — 協定版本的查詢參數鍵。
- prefix
- authenticator
方法
attach(config)
這是 WalletHandlers 類別的主要方法。它為特定使用者操作(例如'登入'、'支付')將必要的 DID Connect 路由附加到您的 Express 應用程式中。此方法建立了一整套端點來處理整個連線生命週期,從權杖產生到錢包回應處理。
附加後,會為給定的 action 建立以下路由:
GET {prefix}/{action}/token: 建立新的會話權杖。POST {prefix}/{action}/token: 建立新的會話權杖。GET {prefix}/{action}/status: 檢查會話權杖的狀態(例如,等待中、已掃描、已批准)。GET {prefix}/{action}/timeout: 手動使會話權杖過期。GET {prefix}/{action}/auth: 錢包用來擷取驗證需求的端點。POST {prefix}/{action}/auth: 錢包用來提交已簽章回應的端點。
參數
- config
object(required) — 用於附加路由的設定物件。- app
object(required) — Express 應用程式實例。 - action
string(required) — 此工作流程的唯一名稱(例如,'login'、'claim-asset')。這將成為 URL 的一部分。 - onAuth
function(required) — 在使用者成功完成其錢包中的流程後執行的回呼函式。您可以在此處處理已驗證的資料。 - claims
object[]— 一個可選的聲明陣列,用於向使用者請求(例如,個人資料、簽章)。 - onStart
function— 一個可選的回呼函式,在新會話開始時執行。 - onConnect
function— 一個可選的回呼函式,在錢包掃描代碼時執行。它會覆寫此特定操作的建構函式中的onConnect。 - onDecline
function— 一個可選的回呼函式,如果使用者在其錢包中拒絕請求,則會執行。 - onComplete
function— 一個可選的回呼函式,在整個工作流程完成且會話權杖被銷毀後執行。 - onExpire
function— 一個可選的回呼函式,用於處理會話權杖過期的情況。 - onError
function(default:console.error) — 一個可選的回呼函式,用於處理流程中的任何錯誤。 - authPrincipal
boolean | string(default:true) — 是否先請求authPrincipal聲明以建立使用者的 DID。 - persistentDynamicClaims
boolean(default:false) — 是否在會話儲存中持久化動態產生的聲明。
- app
範例
附加登入處理程式
const express = require('express');
// ... 從建構函式範例中設定 authenticator 和 tokenStorage
const app = express();
const handlers = new WalletHandlers({ authenticator, tokenStorage });
handlers.attach({
app,
action: 'login',
claims: [{ type: 'profile' }], // 請求使用者的個人資料
onAuth: async ({ userDid, claims }) => {
// 成功登入後的核心邏輯。
// 在您的資料庫中使用 userDid 尋找或建立使用者。
const profile = claims.find(x => x.type === 'profile');
console.log(`使用者 ${userDid} 已登入,名稱為:${profile.fullName}。`);
// 現在您可以為使用者的 Web 會話設定 cookie 或 JWT。
},
onComplete: ({ token }) => {
console.log(`會話 ${token} 已完成並已清除。`);
},
onError: ({ error }) => {
console.error('登入流程中發生錯誤:', error);
}
});
app.listen(3000, () => {
console.log('DID Connect 伺服器正在 3000 連接埠上執行');
});事件
由於 WalletHandlers 擴充了 EventEmitter 並監聽 tokenStorage 實例,您可以訂閱事件以監控會話的生命週期。這對於向使用者提供即時回饋特別有用,例如,使用 WebSockets 在掃描 QR code 時更新 UI。
| Event | Payload | Description |
|---|---|---|
created | object | 當建立新會話權杖時發出。負載包含權杖和初始會話資料。 |
updated | object | 當會話更新時發出。負載包含更新後的會話資料。常見用途是檢查 status: 'scanned'。 |
deleted | object | 當會話權杖被銷毀時發出,無論是完成、過期或手動超時。負載包含被移除的權杖。 |
範例
監聽會話事件
// 假設 'io' 是附加到您 Express 應用程式的 Socket.IO 伺服器實例
handlers.on('updated', (payload) => {
// 通知特定 Web 客戶端 QR code 已被掃描
if (payload.status === 'scanned') {
console.log(`錢包已掃描權杖:${payload.token}`);
// 'sid' (socket ID) 應在會話建立時儲存於會話中
if (payload.sid) {
io.to(payload.sid).emit('wallet_scanned');
}
}
});
handlers.on('deleted', ({ token }) => {
console.log(`權杖 ${token} 已從儲存中刪除。`);
});