meteor-accounts について
Meteor のアカウント設定を支援するスキルです。パスワード、OAuth、パスワードレス認証、二要素認証、トークン保存、メール処理を扱い、パッケージ選定と安全な設定を案内します。
主な機能
- 01パスワードとアカウント作成フロー
- 02OAuth プロバイダー設定
- 03パスワードレスログイントークン
- 04TOTP による二要素認証
- 05HttpOnly Cookie でのトークン保存
- 06メール確認とパスワードリセット
活用シーン
- 01Meteor アプリの認証パッケージ選定
- 02Google などのプロバイダーログイン追加
- 03レジュームトークンの HttpOnly Cookie への移行
- 04パスワードレスまたは TOTP ログインの実装
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ meteor/ agent-skills --skill meteor-accountsインストール後、Claude Code で/meteor-accountsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/eval-cases.mdhttp-only-cookies.mdoauth-services.mdpassword-flows.mdpasswordless-requests.mdusers-collection.md詳細
Meteor アカウント
accounts-base に、accounts-password や
accounts-google などのバリエーションパッケージを組み合わせます。Meteor はユーザーを Meteor.users に保存し、そのドキュメントに対応付けられた再開トークンをクライアントに渡します。
判断の流れ
- ユーザー名とパスワードを使いますか?
accounts-passwordを追加します。 - ソーシャルログインを使いますか?
accounts-baseとプロバイダーパッケージ(例:accounts-google)を追加し、サービスを設定します。 - マジックリンクを使いますか?
accounts-passwordlessを追加します。 - 2FA を使いますか?
accounts-passwordにaccounts-2faを追加します。 - クライアントでトークンを保存しますか? デフォルトは Web Storage です。Meteor 3.3 以降では HttpOnly Cookie フローがサポートされています。以下のセクションを参照してください。
カスタムユーザーコレクションを使う場合は、アプリが読み取りやバリデーターを実行する前に、両方のランタイムを設定します。3.6 RC ではコレクションのセットアップと公開時の検索が修正されています。プロファイルのルールを変更する前に、コレクションの識別とクライアント書き込みポリシーを確認してください。
ユーザー名とパスワード
// server/accounts.js
import { Accounts } from "meteor/accounts-base";
import { Meteor } from "meteor/meteor";
Meteor.startup(() => {
Accounts.config({
sendVerificationEmail: true,
});
Accounts.emailTemplates.siteName = "My App";
Accounts.emailTemplates.from = "[email protected]";
});
from アドレスは必須です。省略すると、Meteor 3.5 以降ではサーバーに警告が記録されます。
クライアントのサインアップフォームが Accounts.createUser または Accounts.createUserAsync を呼び出す場合は、forbidClientAccountCreation: true を設定しないでください。サーバーはそのリクエストを 403 Signups forbidden で拒否します。招待制または管理者によるユーザー作成の場合は、クライアントとサーバーの両方でこのオプションを設定し、公開サインアップ UI を削除して、独自の認可チェックを行った後に、信頼できるサーバーコードからのみ Accounts.createUserAsync を呼び出してください。
// client/signin.js (Meteor 3.5+)
import { Meteor } from "meteor/meteor";
import { Accounts } from "meteor/accounts-base";
async function signUp({ email, password }) {
await Accounts.createUserAsync({ email, password });
}
async function signIn({ email, password }) {
await Meteor.loginWithPasswordAsync(email, password);
}
クライアントでは Accounts.createUser(options, callback) も引き続きサポートされています。Meteor.loginWithPasswordAsync は Meteor 3.5 で追加されました。以前の 3.x では、Meteor.loginWithPassword のコールバック形式を使うか、Promise でラップしてください。
サーバーでは await Accounts.createUserAsync(options) と await Accounts.setPasswordAsync(userId, newPassword) を使います。
HttpOnly Cookie(Meteor 3.3 以降)
トークンの保存先はデフォルトで Web Storage です。再開トークンを HttpOnly Cookie に移し、クライアントのタブ内だけでメモリに保持するには、次のようにします。
// server
Meteor.startup(() => {
Accounts.config({
clientStorage: "none",
useHttpOnlyCookies: true,
});
});
// settings.json (public; surfaces the same flags to the client)
{
"public": {
"packages": {
"accounts": {
"clientStorage": "none",
"useHttpOnlyCookies": true
}
}
}
}
再起動後にログインすると、Meteor.loginToken* は localStorage に表示されなくなり、ブラウザーには HttpOnly の meteor_login_token Cookie が設定されます。各タブはそれぞれの認証情報をメモリ内に保持します。DDP 認証では引き続き再開トークンをメモリに読み込みます。そのため、アプリケーションのオリジンですでに実行中の悪意あるスクリプトからトークンを保護できるわけではありません。
[email protected](Meteor 3.5.2)では、サーバー側でもオプトインした場合にのみ、サーバーが Cookie エンドポイントを処理します。そのため、クライアント側だけで設定すると、後続のハンドラーから HTML レスポンスや 404 が返されることがあります。/set の本文サイズ上限は 4096 バイトです。それを超えるリクエストは HTTP 413 を返します。ルート、バージョンの境界、診断チェックについてはCookie エンドポイントのトラブルシューティングを参照してください。Meteor 3.6-beta.1 の [email protected] では、信頼できるオリジンと有効なトークンも必要になり、SameSite=Strict が使用され、アドレスごとの独立したエンドポイントレート制限が追加されます。アップグレードする前に、カスタムの呼び出し元とクロスサイトのエントリーフローを確認してください。RC では [email protected] が使用されます。再試行や認証情報の破棄を行う前に、無効なセッションと一時的なエラーまたはレート制限によるレスポンスを見分けてください。
OAuth(Google の例)
// server/oauth.js
import { ServiceConfiguration } from "meteor/service-configuration";
await ServiceConfiguration.configurations.upsertAsync(
{ service: "google" },
{
$set: {
clientId: process.env.GOOGLE_CLIENT_ID,
secret: process.env.GOOGLE_CLIENT_SECRET,
loginStyle: "popup",
},
},
);
// client
Meteor.loginWithGoogle(
{ requestPermissions: ["email", "profile"] },
(err) => { if (err) console.error(err); },
);
モバイル環境、または window.close / window.opener がない環境では loginStyle: "redirect" を使ってください。各プロバイダーには専用の accounts-<service> パッケージが用意されています。accounts-google、accounts-github、accounts-facebook、
accounts-twitter、accounts-apple、
accounts-meetup、accounts-weibo です。
OAuth シークレットを保存時に暗号化するには、oauth-encryption を追加して、Accounts.config に oauthSecretKey を渡します。これにより、プロバイダーのアプリケーションシークレットと、サポート対象のプロバイダー固有のユーザートークンフィールドが、ServiceConfiguration.configurations.secret に封印されます。汎用の Meteor.users.services.<provider>.secret フィールドは作成されません。meteor-security を参照してください。
メールアドレスの確認とパスワードのリセット
// client
Accounts.forgotPassword({ email }, (err) => { ... });
// reset page
Accounts.resetPassword(token, newPassword, (err) => { ... });
// verify email
Accounts.verifyEmail(token, (err) => { ... });
メールに記載する URL パターンをカスタマイズします。
Accounts.urls.resetPassword = (token) =>
Meteor.absoluteUrl(`reset/${token}`);
Accounts.urls.verifyEmail = (token) =>
Meteor.absoluteUrl(`verify/${token}`);
どちらのセッターも非同期関数を受け付けます(Meteor 3.x)。
メッセージをカスタマイズします。
Accounts.emailTemplates.resetPassword.subject = () => "Reset your password";
Accounts.emailTemplates.resetPassword.text = (user, url) =>
`Reset link: ${url}`;
パスワードレス
accounts-passwordless を追加します。ワンタイムコードまたはリンクをリクエストし、同じセレクターでコードを送信します。
Accounts.requestLoginTokenForUser(
{
selector: { email },
userData: { email },
options: { userCreationDisabled: false },
},
(error) => { if (error) console.error(error); },
);
Meteor.passwordlessLoginWithToken(
{ email },
token,
(error) => { if (error) console.error(error); },
);
サインインのみのフローでは userCreationDisabled: true を設定します。サーバーで tokenSequenceLength、loginTokenExpirationHours、および Accounts.emailTemplates.sendLoginToken テンプレートを設定します。トークンリクエストメソッドは不正利用に注意が必要なエンドポイントとして扱い、繰り返しのリクエストをレート制限します。Meteor 3.6-beta.1 の [email protected] および [email protected] では、ルックアップ/作成の前にリクエスト全体が検証され、デフォルトの Accounts DDP レートルールが適用されます。カスタムの呼び出し元や以前のパッケージについては、パスワードレスのリクエスト境界を参照してください。RC では [email protected] と [email protected] の組み合わせを使用します。デフォルトのリミッターを維持し、コールバックエラーが発生しても即時の再試行ループに陥らないようにします。
2FA
accounts-2fa は TOTP を追加します。ログインフローは次のとおりです。
- クライアントは Meteor 3.5 以降では
Meteor.loginWithPasswordAsync(user, password)を、古い 3.x ではMeteor.loginWithPasswordのコールバック形式を呼び出します。 - サーバーは
error.error === 'no-2fa-code'で拒否します。 - クライアントはコードの入力を求め、
Meteor.loginWithPasswordAnd2faCode(user, password, code, cb)で再試行します。
アンチパターン
- OAuth シークレットを
Meteor.settings.publicに保存します。クライアントからpublicが見えてしまいます。シークレットはsettings.jsonのトップレベルに置いてください。 - カスタムのパスワードハッシュを作成します。
accounts-passwordは bcrypt を使用するため、信頼してください。 - パスワードを受け取るメソッドで
forbidClientAccountCreationを回避します。同じリスクがあります。 - 遅延パス内で
Accounts.config({ ... })を実行します。トップレベルまたはMeteor.startupで呼び出してください。
関連項目
references/password-flows.mdreferences/oauth-services.mdreferences/eval-cases.md- OAuth シークレットの暗号化と CSP については、
meteor-securityスキルを参照してください。