SDK
Node.js SDK
@authon/node — JWT検証、ユーザー管理、あらゆるNode.jsバックエンドフレームワークへのAuthon統合のためのサーバーサイドSDK。
npm: @authon/nodeNode.js 18+ESM / CJS
インストール
bash
npm install @authon/node初期化
単一の AuthonBackend インスタンスを作成してアプリ全体で再利用。シークレットキーを使用し — クライアントには絶対に公開しないでください。
lib/authon.ts
import { AuthonBackend } from "@authon/node";
export const authon = new AuthonBackend(
process.env.AUTHON_SECRET_KEY!, // sk_live_... or sk_test_...
{
// Optional — override the API base URL
apiUrl: "https://api.authon.dev",
}
);シークレットキー(
sk_live_)をクライアントサイドで使用しないでください。プロジェクトへの完全な管理者アクセス権を付与します。トークン検証
クライアントから Authorization ヘッダーで送信されたJWTアクセストークンを検証。トークンが有効な場合、完全なユーザーオブジェクトを返します。
ts
import { authon } from "@/lib/authon";
// Verify token and get the AuthonUser
async function getAuthenticatedUser(request: Request) {
const authHeader = request.headers.get("Authorization");
if (!authHeader?.startsWith("Bearer ")) return null;
const token = authHeader.slice(7);
try {
const user = await authon.verifyToken(token);
return user;
} catch {
return null;
}
}
// user is an AuthonUser:
// {
// id, projectId, email, displayName, avatarUrl, phone,
// emailVerified, phoneVerified, isBanned,
// publicMetadata, lastSignInAt, signInCount,
// createdAt, updatedAt
// }ユーザー管理
authon.users ネームスペースはプロジェクトのユーザーに対する完全なCRUD操作を提供します。
users.list()
オプションの検索フィルタリングでユーザーをページネーション。
ts
const result = await authon.users.list({
page: 1, // 1-indexed page number
limit: 20, // results per page (max 100)
search: "john", // search by email or display name
});
// result: { data: AuthonUser[], total: number, page: number, limit: number }
console.log(`${result.total} users, showing page ${result.page}`);users.get()
ts
const user = await authon.users.get("usr_abc123");
console.log(user.email, user.displayName);users.create()
サインアップフローを経由せずに直接ユーザーを作成。ユーザーのインポートや管理者アカウントの作成に便利。
ts
const user = await authon.users.create({
email: "newuser@example.com",
password: "securepassword", // optional — omit for OAuth-only users
displayName: "New User",
});users.update()
publicMetadata.
ts
const updated = await authon.users.update("usr_abc123", {
displayName: "Updated Name",
publicMetadata: {
plan: "pro",
onboarded: true,
orgId: "org_xyz",
},
});users.delete()
ts
// Permanently delete a user and all associated sessions
await authon.users.delete("usr_abc123");users.ban() / users.unban()
ユーザーをバンするとすべてのアクティブセッションが取り消され、以降のログインが防止されます。ユーザーレコードは保持されます — 永久削除には delete() を使用してください。
ts
// Ban a user (revokes all sessions)
const banned = await authon.users.ban("usr_abc123", "Violated ToS section 4.2");
console.log(banned.isBanned); // true
// Restore a banned user
const unbanned = await authon.users.unban("usr_abc123");
console.log(unbanned.isBanned); // falseExpressミドルウェア
expressMiddleware メソッドはトークンを検証して req.authonUser.
middleware/auth.ts
import express from "express";
import { authon } from "@/lib/authon";
const app = express();
// Optional — apply globally
app.use(async (req, res, next) => {
const authHeader = req.headers.authorization;
if (authHeader?.startsWith("Bearer ")) {
try {
req.authonUser = await authon.verifyToken(authHeader.slice(7));
} catch {
// Invalid token — req.authonUser remains undefined
}
}
next();
});
// Protected route
app.get("/api/me", (req, res) => {
if (!req.authonUser) {
return res.status(401).json({ error: "Unauthorized" });
}
res.json({ user: req.authonUser });
});
// TypeScript augmentation
declare global {
namespace Express {
interface Request {
authonUser?: import("@authon/shared").AuthonUser;
}
}
}Webhook検証
authon.webhooks.verify() で受信Webhookペイロードを検証。タイミング攻撃を防ぐためにタイミングセーフ比較を使用。
routes/webhooks.ts
import express from "express";
import { authon } from "@/lib/authon";
const router = express.Router();
// IMPORTANT: use raw body parser for webhook routes
router.post(
"/webhooks/authon",
express.raw({ type: "application/json" }),
(req, res) => {
const signature = req.headers["authon-signature"] as string;
let event: Record<string, unknown>;
try {
event = authon.webhooks.verify(
req.body, // Buffer — raw request body
signature, // "sha256=abc123..."
process.env.AUTHON_WEBHOOK_SECRET!,
);
} catch {
return res.status(401).json({ error: "Invalid signature" });
}
// Process the verified event
switch (event.type) {
case "user.created": {
const user = (event.data as any).user;
console.log("New user signed up:", user.email);
// e.g. add to CRM, send welcome email
break;
}
case "user.banned": {
const user = (event.data as any).user;
console.log("User banned:", user.id);
break;
}
case "session.revoked": {
console.log("Session revoked:", event.id);
break;
}
}
res.json({ received: true });
}
);
export default router;