Skip to content

2段階認証 ​

ログインのときに、パスワードに加えて、もう1つの手段で本人を確かめる仕組みです。

手段 ​

手段値強さ説明
パスキーPASSKEY強い端末の指紋・顔認証・PIN、またはセキュリティキー(WebAuthn)。なりすましのサイトでは使えず、いちばん安全。1人で何個でも登録できる
認証アプリTOTP強いGoogle Authenticator などに表示される6桁のコード
メールのコードEMAIL弱い登録しているメールアドレスに届く6桁のコード(10分・5回まで)。メールを見られると破られる
予備のコードRECOVERY_CODE強い最初の手段を登録したときに8個作る。1回ずつ使える。端末をなくしたとき用

どれか1つでも登録していれば「2段階認証を使っている」ことになります。

どの手段を使うか ​

  1. 登録するのは本人: 個人の設定で、使う手段を好きなだけ登録します(パスキーをおすすめとして先頭に出します)。
  2. ログインでは、登録しているうちいちばん強いものを先に出す: パスキー → 認証アプリ → メールのコードの順。「別の方法を使う」で、登録しているほかの手段や予備のコードに切り替えられます。パスキーを使えないブラウザでは、パスキーを出しません。
  3. 画面が認める手段に絞る: 画面ごとに「メールのコードでもよいか」を決めます。認めない画面では、メールのコードで確かめただけでは入れません(パスキーか認証アプリを求めます)。
    • 管理画面: 認めない(LASE_TWO_FACTOR_ADMIN_ALLOW_EMAIL)
    • パートナー画面: 認める(LASE_TWO_FACTOR_PARTNER_ALLOW_EMAIL)
    • 組織の画面: その組織の管理者が「組織の設定 → セキュリティ」で選ぶ(tenants.two_factor_allow_email。既定は認める)
  4. 信頼できるデバイスなら省く: 確かめるときに「このデバイスを信頼する」を選ぶと、そのブラウザでは一定の日数(既定30日)2段階目を省きます。ただし、そのとき使った手段を画面が認めているときだけです(メールのコードで信頼したデバイスでも、管理画面では省きません)。

考え方 ​

  • 登録と確認は人(users)が持つ: 認証アプリの鍵・予備のコードは users に(暗号化して)、パスキーは passkeys に、信頼できるデバイスは trusted_devices に持ちます。どの組織・画面でも同じものを使います。2段階認証を使っている人には、ログインのたびに2段階目を求めます。
  • 求めるかどうかは画面が決める: 管理画面は設定で求めます(既定で求める)。パートナー画面は設定で選びます。組織の画面は、その組織の管理者が選びます。
  • 確かめるのは画面に入るところ: authorize:admin・authorize:partner・authorize:tenant の直後に、その画面が求めているのに、このセッションで(その画面が認める手段で)まだ確かめていなければ 403(code: TWO_FACTOR_REQUIRED。allowEmail 付き)を返します。画面は2段階認証の画面(two-factor)へ移り、使っている人には確かめることを、使っていない人には登録を求めます。
  • 特定の人だけを免除はしない: 通れない人のために、予備のコードと、運営による解除(管理画面のユーザーの詳細)を用意します。
  • 手段を変えるには本人の確認が要る: 手段を足すのと予備のコードの作り直しは、このセッションで2段階認証を確かめてから。手段を消すのとやめるのは、パスワードで確かめてから。最後の手段を消すと、予備のコードと信頼できるデバイスも消えます。

確かめたこと(と、その手段)はセッションに残します。ルートドメインで確かめた結果は、組織へのログイン用トークン(TenantLoginTokenService)で組織のサブドメイン側のセッションへ引き継ぎます。「ログイン状態を保持する」で戻ってきたセッションは確かめていない扱いなので、求める画面では改めて確かめます(信頼できるデバイスなら省きます)。管理者の代理ログインは、管理者が確かめた手段を引き継ぎます。

信頼できるデバイス ​

クッキー lase_trusted_device にランダムな値を入れ、DB にはそのハッシュだけを持ちます。クッキーは SESSION_DOMAIN に付けるので、組織のサブドメインでも使えます。個人の設定で一覧を見て、1つずつ、またはすべて取り消せます。

パスキー ​

lbuchs/webauthn で確かめます。パスキーを使うドメイン(RP ID)は LASE_TWO_FACTOR_PASSKEY_RP_ID(省略すると APP_DOMAIN)です。組織のサブドメインでも同じパスキーを使えるよう、親のドメインにしてください。送られてきた origin は、そのドメインかそのサブドメインの https だけを認めます(localhost は http でも可)。

設定 ​

設定環境変数既定説明
lase.two_factor.require_for_adminLASE_TWO_FACTOR_REQUIRE_ADMINtrue管理画面で求める
lase.two_factor.admin_allow_emailLASE_TWO_FACTOR_ADMIN_ALLOW_EMAILfalse管理画面でメールのコードを認める
lase.two_factor.require_for_partnerLASE_TWO_FACTOR_REQUIRE_PARTNERfalseパートナー画面で求める
lase.two_factor.partner_allow_emailLASE_TWO_FACTOR_PARTNER_ALLOW_EMAILtrueパートナー画面でメールのコードを認める
lase.two_factor.issuerLASE_TWO_FACTOR_ISSUERアプリの名前認証アプリに出す発行元・パスキーの名前
lase.two_factor.passkey_rp_idLASE_TWO_FACTOR_PASSKEY_RP_IDAPP_DOMAINパスキーを使うドメイン
lase.two_factor.recovery_codes8予備のコードの数
lase.two_factor.email_code_minutes10メールのコードの有効な時間(分)
lase.two_factor.email_code_attempts5メールのコードを試せる回数
lase.two_factor.trusted_device_daysLASE_TWO_FACTOR_TRUSTED_DEVICE_DAYS30信頼できるデバイスで2段階目を省く日数(0 で信頼できるデバイスを使わない)

総当たりを防ぐため、コードを確かめる・メールを送る・パスワードを確かめる API は、人ごと・IP ごとに1分あたり lase.auth.rate_limit_per_minute 回までにしています(throttle:lase-two-factor)。一度使った認証アプリのコードは、有効な間でも使えません。

画面 ​

画面ルート説明
ログイン(公開画面)2段階認証を使っている人は、パスワードのあとに2段階目を確かめる(いちばん強い手段を先に出す)
個人の設定 → 2段階認証account.two-factor手段の一覧・足す・消す(パスワード)・予備のコードの作り直し・信頼できるデバイスの取り消し・やめる
2段階認証が必要two-factor(組織 /two-factor・管理 /admin/two-factor・パートナー /partner/two-factor)求める画面に入ろうとしたときに出す。確かめたら、もとの画面へ戻る。メールのコードを認めない画面(strong=1)では、メールのコードだけの人に、メールのコードで確かめてからパスキーか認証アプリの登録を求める
組織の設定 → セキュリティsettings.security「所属する人に2段階認証を求める」「メールのコードを認める」。自分がその設定で使える手段を持っているときだけ求められる(締め出されないように)
管理画面 → ユーザーの詳細2段階認証を使っているかと、解除(端末をなくした人のため)

部品は TwoFactorChallenge(確かめる)・TwoFactorSetup(手段を足す)・TwoFactorRecoveryCodes(予備のコードを見せる)です。two-factor のルートは AuthRoutes(組織)・AdminRoutes・PartnerRoutes が持ちます。API が TWO_FACTOR_REQUIRED を返すと、useApi が自動でこの画面へ移します(onTwoFactorRequired(path, strong) で変えられます)。

API ​

ログイン ​

メソッドパス説明
POST/api/auth/login2段階認証を使っている人には {"twoFactor": true, "methods": [...], "email": "伏せたアドレス", "trustedDeviceDays": 30} を返し、まだログインさせない(信頼できるデバイスなら、そのままログインさせる)
POST/api/auth/two-factor-challengeログインの2段階目(method と code・recoveryCode・credential のどれか、rememberDevice)。パスワードを確かめてから10分の間だけ
POST/api/auth/two-factor-challenge/emailログインの2段階目のメールのコードを送る
POST/api/auth/two-factor-challenge/passkey-optionsログインの2段階目のパスキーの準備

自分の2段階認証(どの画面でも同じ) ​

メソッドパス説明
GET/api/auth/two-factor自分の状態(enabled・methods・totp・email・passkeys・recoveryCodesRemaining・verified・verifiedMethod・trustedDevices・trustedDeviceDays)
POST/api/auth/two-factor/verifyこのセッションで確かめる(ログインの2段階目と同じ入力)
POST/api/auth/two-factor/email/send確かめるためのメールのコードを送る
POST/api/auth/two-factor/passkeys/authentication-options確かめるためのパスキーの準備
POST/api/auth/two-factor/totp認証アプリの登録を始める(secret・otpauthUrl・qrCodeSvg)
POST/api/auth/two-factor/totp/confirmコードで確かめて使い始める
DELETE/api/auth/two-factor/totp認証アプリをやめる(password)
POST/api/auth/two-factor/emailメールのコードを使い始める準備(確かめるコードを送る)
POST/api/auth/two-factor/email/confirm届いたコードで使い始める
DELETE/api/auth/two-factor/emailメールのコードをやめる(password)
POST/api/auth/two-factor/passkeys/registration-optionsパスキーの登録の準備
POST/api/auth/two-factor/passkeysパスキーを登録する(name・credential)
DELETE/api/auth/two-factor/passkeys/{id}パスキーを消す(password)
POST/api/auth/two-factor/recovery-codes予備のコードを作り直す(このセッションで確かめたあと)
DELETE/api/auth/two-factor/trusted-devices[/{id}]信頼できるデバイスを取り消す(省くと、すべて)
DELETE/api/auth/two-factorすべてやめる(password)

手段を使い始める API は、最初の手段なら予備のコード(recoveryCodes)も返します。手段を足す API は、すでに2段階認証を使っている人なら、このセッションで確かめてから呼びます。

組織・運営 ​

メソッドパス説明
PUT/api/tenant/tenant/two-factor-requirement組織が求めるか・メールのコードを認めるか(required・allowEmail。tenant:write)
DELETE/api/admin/users/{id}/two-factor運営が解除する(すべての手段・予備のコード・信頼できるデバイスを消す)

操作ログには、使い始め・やめた(手段ごと)・予備のコードの使用・運営による解除を残します。