跳到主要內容

簡易登入

本範例提供了一個逐步指南,說明如何使用 DID Connect 實作一個基本的使用者登入系統。目標是使用者的 DID 錢包來驗證使用者,並檢索其基本個人資料,例如姓名和電子郵件地址。這是該程式庫最常見的用途之一。

我們將使用 WalletHandlers 與 Express.js 伺服器整合,並向使用者請求 profile 聲明。

運作方式

登入過程遵循標準的 DID Connect 工作流程:

  1. 初始化

    後端使用應用程式的身份設定一個 WalletAuthenticator,並使用一個 WalletHandlers 實例來管理會話。

  2. 處理器附加

    一個特定的處理器被附加到一個 Express 路由(例如 /api/did/login)。此處理器定義了要請求的資訊(聲明)以及在成功驗證後執行的邏輯(onAuth)。

  3. 使用者互動

    前端顯示一個 DID Connect 按鈕或 QR code,與後端啟動會話。

  4. 錢包批准

    使用者使用其 DID 錢包掃描 QR code,檢視請求(分享其個人資料)並批准。

  5. 後端回呼

    伺服器上的 onAuth 回呼被觸發,接收使用者的 DID(userDid)及其個人資料。

  6. 建立會話

    應用程式現在可以使用這些資訊來建立使用者會話、發行 token 或將使用者個人資料儲存到資料庫。

實作

以下是如何建立一個簡單的登入端點。

步驟 1:初始化 Authenticator 和 Handlers

首先,您需要使用您的應用程式詳細資訊設定 WalletAuthenticator,並使用 WalletHandlers 來管理會話狀態。

簡易登入設定

javascript
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:此物件持有您的應用程式身份(錢包)和將在使用者錢包中顯示給使用者的元資料(appInfochainInfo)。
  • WalletHandlers:此類別協調 DID Connect 會話。它需要一個 authenticator 和一個 tokenStorage 適配器來持久化會話狀態。did-connect-storage-nedb 是一個簡單的基於檔案的儲存,適用於範例。

步驟 2:附加登入處理器

接下來,使用 handlers.attach() 方法建立 API 端點並定義您的登入流程的邏輯。此方法會自動為您建立像 /api/did/login/token/api/did/login/status 這樣的路由。

附加登入處理器

javascript
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:這是最關鍵的部分。此函式僅在使用者成功驗證並批准請求後執行。它接收 userDidclaims 資料。在這裡,我們只是記錄資訊,但在實際應用程式中,這將是您處理使用者會話管理的地方。

執行此伺服器後,您可以使用 DID Connect UX 程式庫整合前端,將其指向 /api/did/login 端點以啟動登入流程。

後續步驟

現在您已經有了一個基本的登入系統,您可以探索更多進階功能: