hollo 館・離れ

鍵の間

ja· en· ko
はじめての人へアプリに「あなたの代わりに投稿していい」という合鍵を渡す仕組みです。

アプリに「あなたの代わりに投稿していい」を、安全に渡せます。パスワードは渡さず、合鍵(トークン)だけ。途中で盗み聞きされても悪用できない作法(PKCE)まで込みです。

鍵の作りは几帳面です。合鍵の引き換えには行ロックがかかり、合言葉の影は時間一定の比較で検められる——同じ券の二度使いも、覗き見も、造りのほうで塞いであります。

見どころ

  • クライアント認証は client_secret_basic / client_secret_post / none(公開クライアント)の三通り
  • /token・/revoke・/userinfoはcsrf()から意図的に外してある(壁のコメントに理由つき)
  • /.well-known/oauth-authorization-server(RFC 8414)の案内板も館の根に立っている

経文の一節

          if (accessGrant.codeChallenge && accessGrant.codeChallengeMethod) {
            if (
              !form.code_verifier ||
              accessGrant.codeChallengeMethod !== "S256"
            ) {
              return c.json(INVALID_GRANT_ERROR, 400);
            }

            const expectedCodeChallenge = await calculatePKCECodeChallenge(
              form.code_verifier,
            );

            if (
              !timingSafeEqualString(
                expectedCodeChallenge,
                accessGrant.codeChallenge,
              )
            ) {
              return c.json(INVALID_GRANT_ERROR, 400);
            }
          }
src/oauth.tsx L323-L343— PKCEの検分——自分で再計算して、時間一定の比較で

さわってみる

アプリは最初に「合言葉の影」だけを渡し、引き換えのとき本体を見せます。鍵の間は影を作り直して比べる——影から合言葉は逆算できません(一方通行の扉と同じ)。

間取り

src/oauth.tsx
/authorizeと/token。PKCE S256、FOR UPDATEの引き換え
src/oauth/middleware.ts
tokenRequired/scopeRequired+クライアント認証三通り
src/oauth/endpoints/metadata.ts
RFC 8414の案内板

となりの部屋

そとへのリンク