ce-auth について
ce-authは、Commerce Engine SDKの認証とユーザー管理の実装パターンを説明するスキルです。ストアフロント開発者向けに、匿名セッション、OTPやパスワード認証、アカウント操作、公開読み取りとセッション処理の使い分けを扱います。
主な機能
- 01匿名セッションの開始
- 02メール、電話、WhatsAppのOTP認証
- 03パスワードログインと登録
- 04パスワードのリセットとトークン更新
- 05ユーザープロフィール管理とログアウト
活用シーン
- 01ストアフロントにログインを追加
- 02パスワードレス認証とアカウント作成
- 03アカウントページとプロフィール更新の実装
- 04カートとチェックアウトのセッション対応
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ commercengine/ skills --skill ce-authインストール後、Claude Code で/ce-authを入力して読み込まれたか確認します。
同梱ファイル.claude-plugin/plugin.json.cursor-plugin/plugin.json
詳細
LLM Docs ヘッダー:
https://llm-docs.commercengine.ioへのすべてのリクエストには、Accept: text/markdownヘッダーを必ず含めてください(または URL パスに.mdを追加してください)。含めない場合、解析可能な Markdown ではなく HTML が返されます。
認証とユーザー管理
前提条件:SDK を初期化しておく必要があります。まだの場合は
setup/を参照してください。
認証を直接実装する場合
Hosted Checkout を使用する場合、ログインと登録は通常、チェックアウトドロワー内で処理されます。チェックアウト外でもストアフロントにログイン状態が必要な場合に限り、カスタムの認証 UI を構築してください。たとえば、次のような場合です。
- アカウントページ
- 保存済み住所
- 注文履歴
- ロイヤルティまたはウォレットのページ
- サインイン状態を維持するヘッダー表示
現在の基本的な考え方
- 公開商品とカテゴリの読み取りには
public()を使用でき、匿名認証は不要です。 - ライブカート、アカウント、チェックアウトのフローにはセッションクライアントを使用してください。
- マネージドセッションモードでは、トークンが必要な最初のリクエスト時に SDK が匿名認証を自動的に開始できます。
- 匿名セッションをすぐに開始する必要がある場合は、起動時に
sdk.ensureAccessToken()を一度呼び出してください。
クイックリファレンス
| 認証方法 | エンドポイント | ユースケース |
|---|---|---|
| 匿名セッションの開始 | sdk.ensureAccessToken() または sdk.auth.getAnonymousToken() | ライブセッションの開始 |
| メール OTP | sdk.auth.loginWithEmail() -> sdk.auth.verifyOtp() | パスワード不要のメールログイン |
| 電話 OTP | sdk.auth.loginWithPhone() -> sdk.auth.verifyOtp() | パスワード不要の電話ログイン |
| WhatsApp OTP | sdk.auth.loginWithWhatsApp() -> sdk.auth.verifyOtp() | パスワード不要の WhatsApp ログイン |
| パスワードログイン | sdk.auth.loginWithPassword() | 従来型のログイン |
| パスワード登録 | sdk.auth.registerWithPassword() -> OTP 検証 | パスワードを使用した登録 |
| パスワードを忘れた場合 | sdk.auth.forgotPassword() -> sdk.auth.resetPassword() | OTP によるパスワードのリセット |
| トークンの更新 | sdk.auth.refreshToken() | 期限切れのアクセストークンの更新 |
判断フロー
User Request
│
├─ Public catalog-only page
│ └─ No auth bootstrap needed; use public()
│
├─ New visitor starting a live session
│ └─ sdk.ensureAccessToken()
│
├─ "Login" / "Sign in"
│ ├─ Passwordless → loginWithEmail/Phone/WhatsApp() → verifyOtp()
│ └─ Password → loginWithPassword()
│
├─ "Register"
│ └─ registerWithPassword() / registerWithPhonePassword() → verifyOtp()
│
├─ "Forgot password"
│ └─ forgotPassword() → resetPassword()
│
├─ "Account" / "Profile"
│ └─ getUserDetails() / updateUserDetails()
│
└─ "Token expired" / 401
└─ refreshToken() or rely on managed session refresh
ユーザーの状態
| 状態 | 作成方法 | 利用可能な機能 |
|---|---|---|
| 公開 | public() アクセサーのみ | 公開カタログ/ストア/ヘルパーの読み取り |
| 匿名セッション | sdk.ensureAccessToken() または /auth/anonymous | カート、チェックアウト、分析、セッションの継続 |
| ログイン済みセッション | OTP 検証、パスワードログイン、またはパスワードリセットの完了 | 匿名セッションで利用できるすべての機能に加え、アカウント、注文、住所、ロイヤルティ |
ユーザー ID と顧客 ID
多くのストアでは、user_id と customer_id は同じ値です。1 人のユーザーが 1 人の顧客に対応します。B2B ストアフロントでは、1 人の顧客に複数のユーザーが紐づくことがあります(たとえば、複数の従業員が利用する企業アカウントなど)。
SDK には、両方を取得するヘルパーが用意されています。
const userId = await sdk.getUserId();
const customerId = await sdk.getCustomerId();
ユーザー ID または顧客 ID が必要な SDK メソッドの多くには、現在のセッションから ID を自動解決する引数なしのオーバーロードがあります。たとえば、sdk.cart.getUserCart()(引数なし)は、ログイン中のユーザーのカートを自動的に取得します。別のユーザーに代わって操作する場合(管理者のシナリオ)に限り、ID を明示的に渡してください。
主なパターン
ライブ匿名セッションを開始する
const sdk = storefront.session();
await sdk.ensureAccessToken();
起動時にすぐセッションを開始したい場合は、この処理を一度呼び出してください。通常のセッション対応のカート、注文、顧客に関する呼び出しの前に、繰り返し実行する必要はありません。
OTP ログインフロー(メール)
const { data, error } = await sdk.auth.loginWithEmail({
email: "[email protected]",
register_if_not_exists: true,
});
if (error) throw error;
const { otp_token, otp_action } = data!;
const { error: verifyError } = await sdk.auth.verifyOtp({
otp: "123456",
otp_token,
otp_action,
});
if (verifyError) throw verifyError;
パスワードログイン
const { data, error } = await sdk.auth.loginWithPassword({
email: "[email protected]",
password: "securepassword",
});
if (error) throw error;
パスワード登録
最新の仕様では、パスワード登録は OTP 検証を先に行います。
const { data, error } = await sdk.auth.registerWithPassword({
email: "[email protected]",
password: "securepassword",
confirm_password: "securepassword",
});
if (error) throw error;
await sdk.auth.verifyOtp({
otp: "123456",
otp_token: data!.otp_token,
otp_action: data!.otp_action,
});
パスワードを忘れた場合
const { data, error } = await sdk.auth.forgotPassword({
email: "[email protected]",
});
if (error) throw error;
await sdk.auth.resetPassword({
otp: "123456",
otp_token: data!.otp_token,
new_password: "newPass123",
confirm_password: "newPass123",
});
ユーザープロフィール
認証クライアントのメソッドには明示的な ID が必要です(引数なしのオーバーロードはありません)。現在のユーザーの ID を取得するには sdk.getUserId() を使用してください。
const userId = await sdk.getUserId();
const { data: userData } = await sdk.auth.getUserDetails({ id: userId! });
await sdk.auth.updateUserDetails({ id: userId! }, {
first_name: "Jane",
last_name: "Doe",
});
主な機能:register_if_not_exists
ログインエンドポイントに register_if_not_exists: true を設定すると、ログインとサインアップの入口を分けずに済みます。ユーザーが存在しない場合、Commerce Engine がアカウントを作成し、OTP フローを続行します。
これはチェックアウト認証にも推奨される方法です。「ゲストチェックアウト」フローは別途ありません。ユーザーがメールアドレスまたは電話番号を入力し、OTP で認証され、必要に応じてアカウントが作成されます。この手間の少ない方法により、住所の確認と注文の紐付けが確実になります。Hosted Checkout は、このフロー全体を自動で処理します。
ログアウト
SDK では、カスタムのログアウトボタン用に sdk.auth.logout() が提供されています。
const { data, error } = await sdk.auth.logout();
logout() はトークンをクリアしません。権限を縮小した新しいトークンを返します。セッションは完全に引き継がれ(同じカート、同じ分析履歴)、ユーザーはログイン状態ではなくなります。SDK の onTokensUpdated コールバックが新しいトークンで呼び出され、Hosted Checkout との双方向同期(authMode: "provided" を使用する場合)によってトークンが自動的に反映されます。手動でトークンをクリアしたり、updateTokens("", "") を呼び出したりする必要はありません。
よくある落とし穴
| レベル | 問題 | 解決策 |
|---|---|---|
| CRITICAL | 認証やアカウント操作に public() を使う | セッションクライアントを使います |
| CRITICAL | すべてのページで匿名認証が必要だと思い込む | 公開読み取りには不要です。ライブセッションフローでのみ必要です |
| HIGH | デフォルトでログインとサインアップのフローを分けて作る | 適切な場合は register_if_not_exists: true を優先します |
| HIGH | ステップ間で otp_token と otp_action を引き継がない | 両方を保持し、verifyOtp() に渡します |
| HIGH | トークンを安全でない方法、または実行環境に適さないストレージに保存する | 環境に適したマネージドセッションストレージを使います |
| MEDIUM | { data, error } を無視する | data を使う前に必ず error を確認します |
関連項目
setup/- SDK のインストールとセッションストレージcart-checkout/- チェックアウトフローと Hosted Checkoutorders/- ログイン済みユーザー向けの注文フローssr-patterns/- 認証の変更に使う Server Actions/関数(Next.js、TanStack Start)