login-with-chatgpt について
login-with-chatgptは、WebアプリにChatGPTアカウントのログインとサーバー経由のResponses呼び出しを追加するSDKです。サーバー、React、AI SDK向けのパッケージがあり、トークンを既定でブラウザーに渡しません。
主な機能
- 01ChatGPTのデバイスフロー認証
- 02Cookieベースのセッション管理
- 03ストリーミングResponsesプロキシ
- 04アカウントごとのモデル検出
- 05Reactログインウィジェットとフック
- 06AI SDKでのテキスト、ツール、画像対応
活用シーン
- 01WebアプリへのChatGPTログイン追加
- 02サーバールート経由のモデル応答ストリーミング
- 03ログインアカウントで利用可能なモデルの選択
- 04AI SDKによる画像生成や編集
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ opencoredev/ login-with-chatgpt --skill login-with-chatgptインストール後、Claude Code で/login-with-chatgptを入力して読み込まれたか確認します。
詳細
ChatGPT でログイン
「ChatGPT アカウントでサインイン」するための SDK です。ユーザーは OpenAI のデバイスフローを通じて認証されます。ハンドラーがトークンを保持し、 Responses 形式の呼び出しを ChatGPT がバックエンドの Codex エンドポイントに プロキシします。 ブラウザーに保持されるのは HttpOnly セッションクッキーだけです。
ルール:コードを書く前にお読みください
- API キーはありません。 認証には各ユーザーの ChatGPT セッションを使います。
OPENAI_API_KEYを追加したり、このフローでapi.openai.comを直接呼び出したり しないでください。リクエストはアプリ独自の/api/chatgpt/responsesプロキシ、 またはauth.proxyFetch(request)を使って構築したサーバールートを経由します。 - モデルを選ぶ前に利用可能なモデルを確認してください。 利用可能なモデルは
アカウントとプランによって異なります。まず
await chatgpt.listModels()(ブラウザー)またはawait auth.getModels(request)(サーバー)を呼び出し、その結果から選んでください。 ハードコードしたallowedModelsによるガードレールを設定するのは問題ありませんが、 サインインしたすべてのアカウントで特定のモデルを使えると仮定してはいけません。 - トークンは原則としてハンドラー内に保持します。 トークンをクライアントに
返すエンドポイントを作成しないでください。通常のアプリコードでは
/responses、/models、またはauth.proxyFetch(request)を使用してください。トークンの 生データをエクスポートするには、明示的にdangerouslyAllowTokenExportを 指定する必要があります。 - 同意ステップは省略できません。 ウィジェットは OpenAI の認証ページの前に
必ず同意ステップを表示します。カスタム UI では、
login()を呼び出す前に 同等の同意画面を表示してください。 - 本番環境では、安定した
secretと共有のsessionStoreが必要です。 デフォルト設定(エフェメラルな secret、メモリー内ストア)では、再起動時に 全員がログアウトし、サーバーレスインスタンス間で問題が発生します。
パッケージ
| パッケージ | 用途 |
|---|---|
@opencoredev/loginwithchatgpt-server | ログイン、セッション、ログアウト、モデル、およびストリーミングプロキシ用の createChatGPTHandler() |
@opencoredev/loginwithchatgpt-react | <LoginWithChatGPT /> ボタン、useLoginWithChatGPT() フック |
@opencoredev/loginwithchatgpt-ai | Vercel AI SDK プロバイダー(ai と @ai-sdk/openai はピア依存関係です) |
@opencoredev/loginwithchatgpt-core | 低レベルの OAuth/デバイスフロー、エラー、型。直接インポートすることはほとんどありません |
bun add @opencoredev/loginwithchatgpt-server @opencoredev/loginwithchatgpt-react @opencoredev/loginwithchatgpt-ai ai @ai-sdk/openai
サーバーハンドラー
1 つのハンドラーが basePath(デフォルトは /api/chatgpt)配下のすべてを
処理します。Web 標準の Request、Response、fetch、および
crypto.subtle を使っているため、これらの API を提供するランタイムで使用してください。
// Next.js: app/api/chatgpt/[...lwc]/route.ts
import { createChatGPTHandler } from "@opencoredev/loginwithchatgpt-server";
const auth = createChatGPTHandler({
secret: process.env.LWC_SECRET, // openssl rand -hex 32
responsesProxy: {
allowedModels: ["gpt-5.5", "gpt-5.4", "gpt-5.4-mini"],
},
});
export const GET = (request: Request) => auth.handler(request);
export const POST = (request: Request) => auth.handler(request);
// Bun
Bun.serve({
routes: {
"/": index,
"/api/chatgpt/*": (req) => auth.handler(req),
},
});
主なオプション:basePath、secret、sessionStore(任意の
get/set/delete キーバリューストア)、cookieName、cookie、
sessionTtlMs(30 日)、defaultModel("gpt-5.5")、
enableResponsesProxy(false にすると /models も無効になります)、responsesProxy
(allowedModels、maxRequestBytes は 40 MiB、rateLimit のデフォルトは
セッションあたり 30 回/分)、allowedOrigins(クロスオリジン CSRF 許可リスト)。
返されるハンドラーのサーバーヘルパー(すべてセッションクッキーを読み取ります):
auth.getSession(request)→{ status, user? }。上流への呼び出しはありません。auth.proxyFetch(request)→ 生のベアラートークンを公開せずに、カスタムサーバー AI ルートで使用できるリクエストスコープの fetch。auth.getModels(request)→ アカウントのモデルスラッグ、またはundefined。auth.dangerouslyGetTokens(request)→ 生トークンを取得するための例外的な手段。dangerouslyAllowTokenExportが必要です。
React でのサインイン
"use client";
import { LoginWithChatGPT } from "@opencoredev/loginwithchatgpt-react";
<LoginWithChatGPT
consent={{ appName: "Acme" }}
onAuthenticated={(user) => console.log("connected", user?.email)}
/>;
ウィジェットはフロー全体を処理します。同意ポップアップ → OpenAI の認証 →
コードのコピー → ポーリング → 「切断」ボタン付きのサインイン済みチップ。
挿入される .lwc-* クラスでスタイルを変更するか、完全なカスタム UI を作る場合は
children レンダー関数を渡してください(その場合は、独自の同意画面を表示し、
openLoginWithChatGPTConsentPopup() を使用してください)。
カスタム UI では、useLoginWithChatGPT({ basePath?, pollIntervalMs?, ... }) が
{ status, user, userCode, verificationUrl, login, logout, copyCode, reopen, isAuthenticated, isPending } を返します。status は
loading | unauthenticated | connecting | pending | authenticated | expired | error のいずれかです。
AI SDK でのストリーミング
ブラウザープロキシプロバイダー。認証情報はサーバー側で Cookie から注入されます。
import { createChatGPTProxyProvider } from "@opencoredev/loginwithchatgpt-ai";
import { streamText } from "ai";
const chatgpt = createChatGPTProxyProvider(); // { basePath } if not /api/chatgpt
const models = await chatgpt.listModels(); // throws ChatGPTProxyError; status 401 = signed out
const model = models.includes("gpt-5.5") ? "gpt-5.5" : models[0];
const result = streamText({ model: chatgpt(model), prompt });
独自の AI ルート向けのサーバープロキシプロバイダー:
import { createChatGPTProxyProvider } from "@opencoredev/loginwithchatgpt-ai";
import { streamText } from "ai";
export async function POST(request: Request) {
const chatgpt = createChatGPTProxyProvider({
fetch: auth.proxyFetch(request),
});
const { prompt } = await request.json();
return streamText({ model: chatgpt(), prompt }).toUIMessageStreamResponse();
}
モデルは、標準の AI SDK messages を介した streamText、generateText、ツール呼び出し、構造化出力、ファイル添付をサポートします。画像はプロバイダー API の主要機能です。プロンプトから画像を生成するには chatgpt.images.generate() を、編集には chatgpt.images.edit() を使用できます。編集では、複数の参照画像、マスク、入力忠実度、カスタムサイズ、品質、形式、圧縮、背景、複数の出力、部分画像コールバックに対応しています。どちらも /responses を介して、ログイン中のユーザーの ChatGPT プランを使用します。API キーは追加しないでください。埋め込みと音声は提供されません。
POST /responses のリクエストごとの調整用ヘッダー:
x-login-with-chatgpt-reasoning-effort(none|low|medium|high|xhigh)および
x-login-with-chatgpt-service-tier(auto|default|flex|priority|fast)。
HTTP ルート(basePath からの相対パス)
| ルート | 用途 |
|---|---|
POST /login | デバイスログインを開始 → { status: "pending", userCode, verificationUrl, interval, expiresAt } |
GET /status | ポーリングを 1 回進め、状態を返す |
GET /session | 上流へのポーリングを行わず、状態を低コストで読み取る |
POST /logout | セッションを削除し、Cookie をクリアする |
GET /models | アカウントのモデルスラッグ(ログアウト中は 401) |
POST /responses | Responses 形式のストリーミングプロキシ |
GET 以外のルートでは、Origin に基づく CSRF 対策を適用します。同一オリジンまたは allowedOrigins のみ許可されます。フロントエンドとバックエンドを分離してデプロイする場合は、SameSite=None Cookie、認証情報付き fetch、CORS ヘッダーも必要です(クロスオリジンガイドを参照)。
本番環境チェックリスト
LWC_SECRETを設定します(デプロイ間で固定してください。ローテーションすると全員がログアウトします)。- 共有の
sessionStore(Redis/DB)を使用します。MemoryStoreは開発専用です。 responsesProxy.allowedModelsを設定します。複数のインスタンスを実行する場合は、共有のrateLimit.storeを渡してください。- HTTPS を使用し、Cookie に
Secureが設定されるようX-Forwarded-Protoを転送します。 /responsesのメタデータ(セッション ID、モデル、ステータス、所要時間)を記録し、プロンプトや添付ファイルは記録しないでください。
エラー
ChatGPTAuthError(core 由来)には .code、.status、.body があります。主なコード:refresh_token_invalid(セッションが無効です。ハンドラーはセッションを削除して expired を報告します。isRefreshTokenInvalid(error) で検出できます)、not_authenticated、token_refresh_failed(再試行可能)、models_request_failed。ブラウザープロバイダーの listModels() は、.status を持つ ChatGPTProxyError をスローします。/responses からの HTTP エラー:
401 not_authenticated、403 model_not_allowed / origin_not_allowed、
413 responses_request_too_large、429 rate_limited(retry-after を伴います)。
ドキュメント
完全なドキュメントは、リポジトリ内の docs/content/docs/(quickstart、
concepts/security、guides/production、reference/*)にあります。ドキュメントサイトでは /llms.txt と、各ページの Markdown を /llms.mdx/docs/<path>/content.md で提供しています。