WebXCOM SDK — Backend Guide

— NODE.JS SERVER SDK —

A guide for handling the full De-OAuth server authorize → get_token flow using the SDK in a Node.js backend. Node.js 백엔드에서 De-OAuth 서버 authorize → get_token 전체 플로우를 SDK로 처리하는 가이드입니다.

🚀 Quick Start

Integrate the WebXCOM backend SDK in 4 steps. 4단계로 WebXCOM 백엔드 SDK를 연동하세요.

1
Install
Install SDK via npm npm으로 SDK 설치
2
Initialize
Create a WebXCOMBackend instance WebXCOMBackend 인스턴스 생성
3
Handle Callback
Mount De-OAuth server callback route De-OAuth 서버 콜백 라우트 마운트
4
Get Slot Info
Query slot info with JWT JWT로 슬롯 정보 조회

E2E Authentication Flow

sequenceDiagram participant B as Browser participant G as Game Backend participant SDK as WebXCOMBackend SDK participant A as De-OAuth 서버 B->>G: POST /login (jwt) G->>SDK: getSlotInfo(jwt) SDK->>A: GET /v1/oauth-meta/authorize A-->>SDK: 200 OK (authorize accepted) A->>SDK: POST /getinfo (callback: code, state) SDK-->>A: 200 OK (received) SDK->>A: POST /v1/oauth-meta/get_token (code) A-->>SDK: slot info (id, access_token, content_address) SDK-->>G: slotInfo object G-->>B: { success: true, data: slotInfo }

Install Installation 설치

Install the SDK and Express using npm. npm을 사용하여 SDK와 Express를 설치합니다.

npm install @webxcom/sdk express
ℹ️ peerDependency
express is a peerDependency. If already installed, no separate installation is needed. express는 peerDependency입니다. 이미 설치되어 있다면 별도 설치가 필요 없습니다.

Import the backend SDK: 백엔드 SDK를 import합니다:

const WebXCOMBackend = require('@webxcom/sdk/backend');

Initialize Initialization 초기화

Create a WebXCOMBackend instance. The clientSecret is securely stored in a closure. WebXCOMBackend 인스턴스를 생성합니다. clientSecret은 클로저로 안전하게 보관됩니다.

ParameterTypeRequiredDescription
authServerUrl string Required De-OAuth server base URL De-OAuth 서버 base URL
clientId string Required Client ID issued from the developer center 개발자센터에서 발급받은 클라이언트 ID
clientSecret string Required Client secret (stored in closure) 클라이언트 시크릿 (클로저로 보관)
redirectUri string Required URL to receive De-OAuth server callbacks (POST route) De-OAuth 서버 콜백 수신 URL (POST 라우트)
const sdk = new WebXCOMBackend({
  authServerUrl: 'http://127.0.0.1:3000',
  clientId:      'your-client-id',
  clientSecret:  process.env.CLIENT_SECRET,
  redirectUri:   'http://localhost:3070/getinfo',
});
⚠️ clientSecret Security ⚠️ clientSecret 보안
clientSecret is not stored in instance variables (closure pattern). Always manage it via environment variables (process.env.CLIENT_SECRET). Never hardcode it. clientSecret은 인스턴스 변수에 저장되지 않습니다 (클로저 패턴). 반드시 환경 변수(process.env.CLIENT_SECRET)로 관리하세요. 코드에 하드코딩하지 마세요.

Callback Callback Handling 콜백 처리

sdk.handleCallback(req, res)Handles OAuth callbacks sent from the De-OAuth server. De-OAuth 서버에서 보내는 OAuth 콜백을 처리합니다.

Mount it on an Express route as follows: Express 라우트에 다음과 같이 마운트하세요:

app.post('/getinfo', (req, res) => sdk.handleCallback(req, res));
⚠️ Important: Use POST Method ⚠️ 중요: POST 메서드 사용
Must be mounted at the same path as redirectUri using POST. Not GET. 반드시 redirectUri와 동일한 경로에 POST로 마운트하세요. GET이 아닙니다.
How It Works 동작 방식
1. Immediately responds 200 to release the De-OAuth server connection
2. Finds the pending Promise using the state parameter
3. If success=1, exchanges code via get_token and returns slot info
1. De-OAuth 서버 연결 해제를 위해 즉시 200 응답
2. state 파라미터로 대기 중인 Promise 찾기
3. success=1이면 code를 get_token으로 교환하여 슬롯 정보 반환

Slot Info Slot Info Query 슬롯 정보 조회

sdk.getSlotInfo(jwt, options?)Queries the user's slot info using JWT. JWT로 사용자의 슬롯 정보를 조회합니다.

ParameterTypeRequiredDescription
jwt string Required JWT received from the frontend 프론트엔드에서 전달받은 JWT
timeout number Optional Callback wait timeout in ms (default: 15000) 콜백 대기 타임아웃 ms (default: 15000)

Response structure (SlotInfo): 응답 구조 (SlotInfo):

{
  "id": "slot-unique-id",
  "access_token": "eyJhbG...",
  "content_address": "0x742d...",
  "token_nickname": "user-nick",
  "tr_cnt": 3,
  "code": "auth-code"
}

Full Express server example: 전체 Express 서버 예시:

const express = require('express');
const WebXCOMBackend = require('@webxcom/sdk/backend');

const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

const sdk = new WebXCOMBackend({
  authServerUrl: process.env.AUTH_SERVER_URL,
  clientId:      process.env.CLIENT_ID,
  clientSecret:  process.env.CLIENT_SECRET,
  redirectUri:   process.env.REDIRECT_URI,
});

// De-OAuth 서버 콜백 수신 (POST)
app.post('/getinfo', (req, res) => sdk.handleCallback(req, res));

// 게임 로그인 엔드포인트
app.post('/login', async (req, res) => {
  const jwt = req.body.jwt;
  if (!jwt) return res.status(400).json({ error: 'JWT required' });

  try {
    const slotInfo = await sdk.getSlotInfo(jwt);
    // slotInfo.id → 유저 고유 ID
    // slotInfo.content_address → 블록체인 주소
    res.json({ success: true, data: slotInfo });
  } catch (err) {
    if (err.message.includes('EXPIRED_TOKEN')) {
      return res.status(401).json({ error: 'JWT expired' });
    }
    if (err.message.includes('timeout')) {
      return res.status(408).json({ error: 'Timeout' });
    }
    return res.status(500).json({ error: 'Server error' });
  }
});

app.listen(3070, () => console.log('Game server running on port 3070'));

Manage Shutdown & Error Handling 종료 & 에러 처리

sdk.shutdown()Immediately rejects all pending Promises when the server shuts down. 서버 종료 시 대기 중인 모든 Promise를 즉시 실패 처리합니다.

// 서버 종료 시 정리
process.on('SIGTERM', () => {
  sdk.shutdown();
  server.close(() => process.exit(0));
});

process.on('SIGINT', () => {
  sdk.shutdown();
  process.exit(0);
});

Error message reference: 에러 메시지 참조:

Error MessageCauseHTTP Status
authorize callback timeout No De-OAuth server callback received within 15s 15초 내 De-OAuth 서버 콜백 미수신 408
EXPIRED_TOKEN JWT expired JWT 만료 401
AUTHORIZE_ERROR De-OAuth server authorization error De-OAuth 서버 인가 오류 502
authorize callback rejected De-OAuth server callback failure response De-OAuth 서버 콜백 실패 응답 502
shutdown Cannot process request during server shutdown 서버 종료 중 요청 처리 불가 503