🔑 API Key認証の実装:クライアントにAPIを有料で提供する

これまでの章では、私たちは「他人のAPIを呼び出す」側の役割を果たしてきました(Stripeや緑界、OpenAIなどへのリクエスト)。 しかし、もしあなたが超高性能なAI画像生成モデルや、極めて正確な株価予測アルゴリズムを開発した場合、それをAPIとして世界中のエンジニアに有料で提供したいと思いませんか?

そのためには、**「API Key認証システム」**を構築する必要があります!

この章では、ビジネスレベルのAPI Keyロジックをゼロから実装する方法を解説します。キーの生成、認証、使用量の計算までを網羅します!


1. API Keyとは何か?

API Keyとは、推測が困難な長い文字列(例:sk_live_abc123def456...)です。 クライアントが料金を支払った後、このKeyを発行します。以後、クライアントがあなたのAPIを呼び出す際には、HTTP HeaderにこのKeyを含める必要があります。バックエンドはこのKeyを見ることで「これは王大明さんのリクエストだ、1ポイント消費しよう」と判断します。

データベース設計 (PostgreSQL例)

API Keyを管理するためには、関連テーブルをデータベースに作成する必要があります:

CREATE TABLE api_keys (
  id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
  user_id UUID REFERENCES users(id), -- このKeyの所有者
  key_value VARCHAR(255) UNIQUE NOT NULL, -- 実際の文字列 (例: sk_live_...)
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  last_used_at TIMESTAMP WITH TIME ZONE,
  is_active BOOLEAN DEFAULT TRUE,
  usage_count INTEGER DEFAULT 0 -- 呼び出し回数の統計
);

2. 安全なAPI Keyを生成する

API Keyは決して連番(001, 002など)にしてはいけません。そうするとハッカーに簡単に推測されてしまいます。 Node.jsの組み込みモジュールcryptoを使用して、ランダムで安全な文字列を生成しましょう。

// src/app/api/generate-key/route.ts
import { NextResponse } from 'next/server';
import crypto from 'crypto';
import { db } from '@/lib/db'; // あなたのデータベース接続

// ランダム文字列生成のヘルパー関数
function generateApiKey() {
  // 32バイトのランダムな16進数文字列を生成し、カスタムプレフィックスを付加
  const randomStr = crypto.randomBytes(32).toString('hex');
  return `vibe_sk_${randomStr}`; 
}

export async function POST(request: Request) {
  // ユーザーがログインしていると仮定
  const userId = 'user-123'; 
  
  const newKey = generateApiKey();

  // データベースに保存
  const insertedKey = await db.api_keys.insert({
    user_id: userId,
    key_value: newKey,
    is_active: true
  });

  return NextResponse.json({ 
    message: "API Keyが正常に生成されました!この機会に必ず保存してください。二度と表示されません。",
    apiKey: newKey 
  });
}

⚠️ セキュリティプラクティス:業界で最も厳格な実装では、データベースにAPI Keyを平文で保存せず、hash(API Key)を保存します。これはパスワードと同様で、万が一データベースが侵害されても、ハッカーは元のKeyを取得できません。ただし小規模なプロジェクトでは、平文や暗号化して保存することも許容されるトレードオフです。


3. コアAPIに「認証ゲート」を実装する

クライアントがvibe_sk_xxx...というKeyを取得しました。 彼らが有料の「AI株価予測API」を呼び出す際には、入り口でガードマンによるチェックが必要です。

業界標準の方法は、クライアントにAPI KeyをHTTP HeaderのAuthorization: Bearer <API_KEY>に入れてもらうことです。

// src/app/api/stock-predict/route.ts
import { NextResponse } from 'next/server';
import { db } from '@/lib/db';

export async function POST(request: Request) {
  // 1. HeaderからAuthorizationフィールドを取得
  const authHeader = request.headers.get('Authorization');
  
  // 形式が正しいか確認 (Bearer vibe_sk_...)
  if (!authHeader || !authHeader.startsWith('Bearer ')) {
    return NextResponse.json({ error: "API Keyの形式が不正です。'Bearer <YOUR_KEY>'形式で指定してください" }, { status: 401 });
  }

  // 実際のKey文字列を抽出
  const providedKey = authHeader.split(' ')[1];

  // 2. データベースでKeyを照合
  const keyRecord = await db.api_keys.findUnique({
    where: { key_value: providedKey }
  });

  // Keyが存在しない、または無効化されている場合
  if (!keyRecord || !keyRecord.is_active) {
    return NextResponse.json({ error: "無効または非アクティブなAPI Keyです" }, { status: 403 });
  }

  // 3. ユーザーの利用可能残高を確認(オプション)
  const user = await db.users.findUnique({ where: { id: keyRecord.user_id }});
  if (user.credits <= 0) {
    return NextResponse.json({ error: "残高不足です。アカウントにチャージしてください。" }, { status: 402 }); 
    // 402 Payment Requiredはこの場面にぴったり!
  }

  // ------------------------------------
  // あなたの価値あるビジネスロジックを実行
  // ------------------------------------
  const predictionResult = { stock: "TSLA", trend: "UP", confidence: 0.95 };

  // 4. 処理完了後、ポイントを減算し統計を更新
  await db.users.update({
    where: { id: user.id },
    data: { credits: user.credits - 1 }
  });

  // Keyの最終使用日時と回数も記録
  await db.api_keys.update({
    where: { id: keyRecord.id },
    data: { 
      usage_count: keyRecord.usage_count + 1,
      last_used_at: new Date()
    }
  });

  // 5. 充実したResponseを返却!
  return NextResponse.json({
    data: predictionResult,
    meta: {
      credits_remaining: user.credits - 1
    }
  });
}

4. クライアントはどうやってAPIを呼び出すか?

この完璧なゲートを実装したことで、あなたは堂々とAPI公式ドキュメントを書くことができます! クライアントには以下の方法でAPIを呼び出すように指導しましょう:

Fetchを使用する場合 (JavaScript/TypeScript):

const response = await fetch('https://api.yourdomain.com/stock-predict', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    // ここにクライアントが購入したAPI Keyを設定!
    'Authorization': 'Bearer vibe_sk_abc123...'
  },
  body: JSON.stringify({ symbol: "TSLA" })
});
const data = await response.json();

cURLを使用する場合 (ターミナル):

curl -X POST https://api.yourdomain.com/stock-predict \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer vibe_sk_abc123..." \
  -d '{"symbol": "TSLA"}'

素晴らしい!これで完全なB2B(企業間)SaaSビジネスアーキテクチャが完成しました!価値あるアルゴリズムを開発し、このAPI Key認証システムと組み合わせれば、自宅にいながら呼び出し回数(usage_count)が増えるのを見守り、毎月クライアントから料金を徴収できるようになります!💸

完全なチュートリアルをロック解除

このチャプターは有料コンテンツです。プロジェクトに参加して、10以上の神レベルのPromptや実際のソースコード例を含む、5000字以上の深い分析をロック解除してください!