認証
成分 API のデータルート(/v1/foods*・/v1/food-groups・/v1/nutrients)は
認証必須です。認証手段は用途に応じて 3 系統あります。
| 系統 | 用途 | 渡し方 |
|---|---|---|
| セッション認証 | ダッシュボード / API キー管理 | Cookie(Better Auth) |
| API キー認証 | 実 API コール(本利用) | X-API-Key ヘッダ |
| お試しトークン | 認証なしで試す(お試し利用) | Authorization: Bearer ヘッダ |
公開のままなのは
GET /v1/meta・/healthzと発行エンドポイントPOST /v1/trial-tokenだけです。 その他のデータルートは、API キーかお試しトークンが無いと一律 401 を返します。
セッション認証(Better Auth)
アカウント登録・ログインは Better Auth のメール+パスワードで行い、
/api/auth/* にマウントされています。API キーの発行・一覧・失効はセッションが必須です。
# サインアップ(成功すると即ログイン状態の Cookie が Set-Cookie で返る)
curl -i -X POST https://api.example.com/api/auth/sign-up/email \
-H 'content-type: application/json' \
-d '{"email":"[email protected]","password":"password1234","name":"me"}'
# サインイン
curl -i -X POST https://api.example.com/api/auth/sign-in/email \
-H 'content-type: application/json' \
-d '{"email":"[email protected]","password":"password1234"}'サインイン/サインアップは IP 単位でブルートフォース対策のレート制限を受けます
(クライアント IP は CF-Connecting-IP)。超過時は 429 を返します。
API キー認証(X-API-Key)
本利用では、セッションで発行した API キーをリクエストの X-API-Key ヘッダに付けます。
キーの tier は free で、レート制限の対象になります(レート制限)。
curl "https://api.example.com/v1/foods/01001" \
-H "X-API-Key: fnk_xxxxxxxxxxxxxxxx"キーの発行・一覧・失効
# 発行:平文キーはこの応答にのみ含まれる(保存されず、再表示もできない)
curl -X POST https://api.example.com/v1/keys -b cookies.txt \
-H 'content-type: application/json' -d '{"name":"my key"}'
# → { "id": "...", "name": "my key", "keyPrefix": "fnk_xxxx", "tier": "free", "key": "fnk_<平文>" }
# 一覧(平文は含まない)
curl https://api.example.com/v1/keys -b cookies.txt
# 失効(本人のキーのみ)
curl -X DELETE https://api.example.com/v1/keys/{id} -b cookies.txt平文キーは保存されません。 発行時の応答に 1 度だけ含まれ、サーバ側は SHA-256 ハッシュのみを保持します。 控え忘れたら失効して再発行してください。他人のキーへの操作・存在しないキーへの失効は
404(存在を秘匿)です。
お試しトークン(Turnstile → Bearer)
認証なしで試したいときは、Cloudflare Turnstile
を 1 回解いて短命トークン(HMAC 署名・有効 24 時間/生涯 30 リクエスト)を得ます。
得たトークンは Authorization: Bearer で渡します。tier は anon です。
# 1) お試しトークンを得る(Turnstile のウィジェットトークンを渡す)
curl -X POST https://api.example.com/v1/trial-token \
-H 'content-type: application/json' -d '{"turnstileToken":"<widget token>"}'
# → { "token": "<payload>.<sig>", "expiresAt": "..." }
# 2) トークンでデータルートを叩く
curl https://api.example.com/v1/food-groups \
-H 'Authorization: Bearer <payload>.<sig>'失敗は一律 401(理由秘匿)
認証の検証失敗は、理由(不在 / 失効 / 期限切れ / 形式不正など)を問わず
HTTP では一律 401 に潰します。これは「どのキーが存在するか」といった情報を
攻撃者に与えないための設計です。エラーの形は エラー を参照してください。