アプリは秘密を持てないので、PKCE で認可コードの横取りを防ぐ。ログイン画面はシステムのブラウザで開く。
OAuth 2.0 は、利用者がパスワードをアプリに渡さずに、別のサービス(認可サーバー。Google や自社の ID 基盤など)でログインして、アプリにアクセストークン(API を使ってよいという許可証)を渡すための決まりです。「誰がログインしたか」を伝える部分は、OAuth の上に作られた OpenID Connect(OIDC)が受け持ちます。
作り方を間違えると、トークンを盗まれて他人になりすまされる事故につながるので、アプリでの正しい作り方を押さえておきます。
アプリで「Google でログイン」や自社の ID 基盤でのログインを作るときは、OAuth 2.0 の認可コードフローに PKCE を付けたものを使います。アプリは中身を解析されるので、秘密の値(クライアントシークレット)を安全に持てません。PKCE はその代わりに、ログインのたびに使い捨ての合言葉を作る仕組みです。
- アプリがランダムな文字列
code_verifierを作り、そのハッシュcode_challenge(S256)をつけてログイン画面を開く。 - 利用者がログインすると、決めておいた戻り先(リダイレクト URI)に認可コードが返る。
- アプリは認可コードと元の
code_verifierをトークンの窓口に送り、アクセストークンとリフレッシュトークンを受け取る。
途中で認可コードを盗まれても、code_verifier を知らなければトークンに交換できません。
(SRE)認証と状態管理(Cookie・セッション・トークン・OAuth)
下の「ブラウザで試す」の図は、Web サービスのサーバーが「Google でログイン」を受け持つ場合の流れです。認可サーバーへリダイレクト → ログインと同意 → 認可コードを持って戻る → コードを code_verifier と一緒にトークンに交換、という順番はアプリでも同じです。違うのは交換する側で、図ではサーバーがクライアントシークレットも付けて交換しますが、アプリではアプリ自身がシークレットなしで code_verifier を付けて交換します。
面接ではこう答える
アプリでのログインは、OAuth 2.0 の認可コードフローに PKCE を付けて使います。アプリは中身を解析されるので秘密の値を持てず、その代わりにログインのたびに使い捨ての code_verifier を作り、そのハッシュを付けてログイン画面を開きます。戻ってきた認可コードをトークンに交換するときに元の code_verifier を送るので、途中で認可コードを盗まれても、verifier を知らない人はトークンに交換できません。
Appとの関わりログイン機能の実装や、ID 基盤とつなぐときの設計、セキュリティの診断の説明で使います。
ネットワーク図を読み込んでいます…