+ 作るログイン
1 / 20
AWS でサービスを作る ― 知識ゼロから、構成を自分で考えられるまで / 全32章

AWS 26:ログイン ― Cognito で認証を借りる

発行
アニメモ公式
版
第2版
改訂
コマ
全20

フォトログはログインを自作し、パスワードを自分の DB に保存していた。認証を自作する危険、Cognito のユーザープールと ID プールの違い、ログインからトークン(JWT)を受け取り API で確かめるまでの流れ、3つのトークンの役目と確かめ方、ソーシャルログイン、API Gateway・ALB との連携、パスワードを DB から消す移行、料金の単位、落とし穴、いつ選ぶかを説明します。

ログインを自作していて、パスワードの扱いが怖い

第25章で、フォトログのセッションを ElastiCache に置きました。ここで改めて、ログインの仕組み全体を見直してみます。フォトログのログインは、ここまで自分で作ってきました。利用者が登録するとパスワードを自分の DB に保存し、ログインのときに照らし合わせて、合っていればセッションを発行しています。

「ログインできる」だけなら、数十行で作れます。でも、安全に作り、それを安全なまま保ち続けるには、図の6つの仕事がすべて要ります。

仕事間違えると何が起きるか
1 パスワードを安全にしまう平文や弱いハッシュで保存すると、DB が漏れた瞬間に全員のパスワードが知られる
2 メールの確認と再設定再設定のリンクが推測できると、他人のアカウントを乗っ取られる
3 二段階認証(MFA)パスワードが漏れただけで入られる
4 総当たりを止めるよくあるパスワードを片っ端から試され、弱い人から破られる
5 Google でログイン手順(OAuth・OIDC)の確認漏れで、なりすましを許す
6 トークンの発行と検証署名や期限の確認漏れで、偽の入館証が通る

しかも怖いのは、多くの人が他のサービスでも同じパスワードを使っていることです。フォトログの DB が漏れれば、利用者のメールや銀行のアカウントまで危なくなります。

この章では、ログインという「自作すると危ない部品」を AWS から借りる、Amazon Cognito(コグニート)を学びます。

※2026年9月時点の情報です。画面・料金・細部は変わることがあります。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 1 / 20
  • ログインを自作していて、パスワードの扱いが怖い
  • 錠
  • パスワードを安全にしまう
  • メール
  • メールの確認と再設定
  • スマホ
  • 二段階認証(MFA)
  • ハッシュ・ソルト・遅い計算
  • リンクの期限・なりすまし
  • ワンタイムコード・パスキー
  • 盾
  • 総当たりを止める
  • インターネット
  • Google でログイン
  • コード
  • トークンの発行と検証
  • 失敗回数・ロック・通知
  • OAuth・OIDC の実装
  • 署名・期限・鍵の交換
  • フォトログはここまで、パスワードを自分の DB に保存し、セッションを ElastiCache(第25章)に置いてきた
  • DB が漏れたら、利用者が他のサービスで使うパスワードまで危なくなる
  • ひらめき
  • ログインは「動く」だけなら簡単。でも安全に作り続けるには、これだけの仕事がある。1つ漏れれば事故。

受付は、専門の会社に任せる

大きなオフィスビルを思い浮かべてください。入口の受付では、警備会社の人が身分証を確かめ、入館証を渡します。各部屋の人は、訪問者の身分証を自分で調べません。入館証が本物かどうかだけを見て、ドアを開けます。

Cognito は、この受付の役目を引き受けます。

ビルの受付フォトログ
警備会社の受付Cognito
身分証を確かめるパスワードや二段階認証で本人か確かめる
入館証トークン(署名入りのデータ。後で詳しく説明)
各部屋フォトログのアプリ(API)
入館証を見てドアを開けるトークンが本物か確かめて、処理をする

この形にすると、パスワードはアプリの DB に一度も入りません。アプリが知っているのは、「Cognito が本人と確かめた、この ID の人」ということだけです。もしアプリの DB が漏れても、パスワードは漏れようがありません。

二段階認証、パスワードの再設定、総当たりの防止、Google などでのログインといった面倒な仕事は、受付側(Cognito)の機能として用意されています。アプリを作る人は、その設定を選ぶだけで済みます。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 2 / 20
  • 受付は、専門の会社に任せる
  • 守られている
  • 書類
  • 会社
  • 受付(Cognito)
  • 入館証
  • 本人確認・入館証の発行
  • 入館証
  • 見せる
  • 各部屋(アプリ)
  • 入館証が本物か確かめる
  • OK
  • パスワードはアプリの DB に一度も入らない
  • OK
  • 二段階認証・再設定・ソーシャルログインは受付側の機能
  • ひらめき
  • 本人確認は専門の受付(Cognito)に任せる。アプリは入館証を確かめるだけ。

「誰か」は Cognito、「何をしてよいか」はアプリ

第3章で、認証(あなたは誰か)と認可(あなたは何をしてよいか)の違いを学びました。ここでもう一度、この2つを分けて考えます。

認証認可
問いあなたは誰?あなたは何をしてよい?
フォトログの例この人は利用者「あおい」本人かあおいさんは、この写真を消してよいか
担当Cognitoアプリ
材料パスワード、MFA のコードトークンに入った利用者 ID(sub)と、DB にある写真の持ち主

Cognito が教えてくれるのは、「この人は sub が a1b2-… の利用者です」という認証の結果までです。「その写真の持ち主は a1b2-… か」を DB で確かめて、消してよいかを決めるのは、アプリの仕事のままです。

ここを勘違いして、「ログインしている人なら何でもできる」作りにすると、他人の写真を消せてしまいます。認証を借りても、認可は自分で書くことを忘れないでください。

もう1つ、第3章の IAM との違いも整理しておきます。IAM は「AWS を操作する人やプログラム」(開発者やサーバー)の認証と認可です。Cognito は「あなたのサービスの利用者」の認証です。フォトログの利用者に IAM ユーザーを作ることはありません。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 3 / 20
  • 「誰か」は Cognito、「何をしてよいか」はアプリ
  • 人
  • 認証(あなたは誰?)
  • 天秤
  • 認可(何をしてよい?)
  • 担当
  • Cognito
  • 担当
  • アプリ
  • 確かめること
  • パスワード・MFA
  • 確かめること
  • 写真の持ち主か・管理者か
  • 結果
  • トークン(sub=利用者の ID)
  • 材料
  • トークンの sub と DB の中身
  • 第3章の IAM は「AWS を操作する人」の認証と認可。Cognito は「サービスの利用者」の認証
  • ひらめき
  • Cognito は「本人か」まで。「この写真を消してよいか」はアプリが判断する。

ユーザープール:利用者の名簿と、ログインの窓口

Cognito の中心はユーザープールです。ユーザープールは、利用者の名簿と、ログインのための機能をひとまとめにしたものです。ふつうは、1つのサービスに1つ作ります。

中身役目
利用者の名簿メールアドレス、名前、そして利用者ごとに変わらない ID(sub)。パスワードもここにだけある
ログイン画面マネージドログイン。Cognito が用意する、登録・ログイン・再設定の画面。色やロゴを変えられる
二段階認証認証アプリのコード、メールのコード、パスキー(指紋や顔で本人確認する仕組み)など
外部の IDGoogle、Apple、会社の ID 基盤などでのログイン

もう1つ大事なのがアプリクライアントです。これは「このユーザープールを、どのアプリが使うか」の登録です。フォトログの Web 版とスマホ版を、別々のクライアントとして登録できます。クライアントごとに、ログインが終わったあとに戻る先の URL(コールバック URL)や、トークンの有効期間を決めます。

Web のブラウザやスマホのように、中身を利用者に見られてしまうアプリでは、クライアントシークレット(合言葉)を使わない設定にします。ブラウザに合言葉を置いても、すぐに読まれてしまうからです。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 4 / 20
  • ユーザープール:利用者の名簿と、ログインの窓口
  • ユーザープール(フォトログ用)
  • 人々
  • 利用者の名簿
  • ブラウザ
  • ログイン画面
  • リンク
  • アプリクライアント
  • メール・名前・sub
  • マネージドログイン
  • 「どのアプリが使うか」の登録
  • スマホ
  • 二段階認証
  • インターネット
  • 外部の ID
  • Web 版とスマホ版で別々に登録できる。 戻り先の URL(コールバック)や トークンの有効期間はここで決める
  • アプリ・メール・パスキー
  • Google・Apple など
  • パスワードは Cognito の中にだけある
  • ひらめき
  • 名簿(誰がいるか)と、ログイン画面・MFA・再設定などの機能をまとめて持つ。アプリごとに1つ作る。

ログインの流れ ①:Cognito の画面でログインする

ここから、ログインしてから写真の一覧を取るまでの流れを、図の舞台で追います。左がブラウザ、上が Cognito、下がフォトログの API です。

利用者が「ログイン」を押すと、ブラウザはCognito のログイン画面(マネージドログイン)へ移ります。利用者は、そこでメールアドレスとパスワードを入れます。二段階認証を有効にしていれば、続けて認証アプリのコードも入れます。「Google でログイン」を選んだ場合は、Google の画面で同意します。

誰が何を見るか
Cognitoパスワード、MFA のコード、Google からの応答
フォトログのアプリ何も見ない

図の小包が「パスワード」を運んでいる先は、Cognito です。フォトログの API には届きません。これが、この仕組みのいちばん大事な点です。

ログイン画面を自分で作り、そこから Cognito の API を呼んでログインさせることもできます。見た目を細かく作り込みたいときの方法です。ただしその場合、パスワードがいったんアプリの画面を通るので、扱いに注意が必要です。まずはマネージドログインから始めるのがおすすめです。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 5 / 20
  • ログインの流れ ①:Cognito の画面でログインする
  • パスワード
  • 鍵
  • Cognito
  • ここで 確かめる
  • ユーザープール
  • ① ログイン画面へ
  • パスワード MFA のコード Google の同意
  • ノートPC
  • ブラウザ
  • サーバー
  • アプリ(API)
  • データベース
  • フォトログ
  • DB
  • ログイン画面は Cognito が用意する(マネージドログイン)。自前の画面から Cognito の API を呼ぶこともできる
  • ひらめき
  • ブラウザを Cognito のログイン画面へ送り、そこで本人確認。アプリはパスワードを一度も見ない。

ログインの流れ ②:トークンを受け取る

本人確認が済むと、Cognito はブラウザを、決めておいたコールバック URL(フォトログのページ)へ戻します。このとき、ブラウザはトークンを受け取ります。

トークンは、「Cognito が、この人を本人と確かめました」ということを書いた、署名入りのデータです。入館証にあたります。

正確には、次の2段階で受け取ります。

段階何が起きるか
戻るときURL に認可コード(一度しか使えない引換券)が付いてくる
交換その引換券を Cognito に渡して、トークンと交換する

この手順は OAuth 2.0 の認可コードフローと呼ばれる、世界共通の決まりです。ブラウザのように合言葉を持てないアプリでは、PKCE(ピクシー)という、引換券を横取りされても使えなくする工夫を合わせて使います。多くのライブラリは、これを自動でやってくれます。

受け取るトークンは3種類あります。ID トークン、アクセストークン、リフレッシュトークンです。それぞれの役目は、この後で説明します。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 6 / 20
  • ログインの流れ ②:トークンを受け取る
  • 鍵
  • Cognito
  • 3種類の トークン
  • ユーザープール
  • ノートPC
  • ② トークン
  • ID アクセス リフレッシュ
  • ブラウザ
  • トークン
  • サーバー
  • アプリ(API)
  • データベース
  • フォトログ
  • DB
  • 実際は「認可コード」をいったん受け取り、それをトークンと交換する(OAuth 2.0 の認可コードフロー)
  • ひらめき
  • 本人確認が済むと、Cognito は署名入りのトークンを返す。これが「入館証」。

ログインの流れ ③:API にトークンを見せる

ログインが済んだブラウザは、フォトログの API を呼ぶたびに、アクセストークンを添えます。HTTP(ブラウザとサーバーのやり取りの決まり)の Authorization という欄(ヘッダー)に、Bearer(持参人)という言葉に続けて書くのが決まりです。

GET /api/photos
Authorization: Bearer eyJraWQiOiJ...

API は、受け取ったトークンについて次のことを確かめます。

確かめること意味
署名は本物かCognito が作ったもので、途中で書き換えられていないか
期限切れではないか古い入館証ではないか
自分宛てか別のアプリ用に発行されたトークンではないか

すべて通れば、トークンの中にある sub(利用者の ID)を取り出し、「この人の写真の一覧」を DB から読んで返します。

ここで大事なのは、API は Cognito に毎回問い合わせなくてよいことです。トークンには署名があるので、API は手元で本物か確かめられます。何万回呼ばれても、Cognito との往復は増えません。これは、第12章の「ステートレス」とも相性がよい形です。どのサーバーが受けても、同じ確かめ方で済みます。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 7 / 20
  • ログインの流れ ③:API にトークンを見せる
  • 鍵
  • Cognito
  • API が 確かめる
  • ユーザープール
  • Authorization:
  • Bearer eyJraWQi…
  • 署名は本物? 期限切れでは? 自分宛て?
  • ノートPC
  • ブラウザ
  • ③ トークンを添える
  • サーバー
  • アプリ(API)
  • データベース
  • フォトログ
  • DB
  • トークン
  • ひらめき
  • ブラウザは API を呼ぶたびにトークンを添える。API は本物か確かめ、中の sub で「誰か」を知る。

3つのトークンと、それぞれの役目

Cognito が返す3つのトークンを整理します。

トークン役目使う場所
ID トークンその人が誰か(名前、メールなど)を伝える画面に「こんにちは、あおいさん」と出すため
アクセストークンAPI を呼んでよいという許可API に添える
リフレッシュトークン新しい ID・アクセストークンをもらう引換券Cognito に渡すだけ。API には送らない

有効期間には、次のような既定値があります。アプリクライアントごとに変えられます。

トークン既定変えられる範囲
ID・アクセス1時間5分〜1日
リフレッシュ30日60分〜10年

なぜ、わざわざ3つに分けるのでしょうか。アクセストークンは短く、リフレッシュトークンは長くすることで、安全と便利を両立するためです。

API に何度も送るアクセストークンは、どこかで盗まれる可能性が相対的に高くなります。でも1時間で切れるので、盗まれても使える時間は短くて済みます。切れたら、ブラウザはリフレッシュトークンを Cognito に渡して、新しいアクセストークンを受け取ります。利用者はログインし直す必要がありません。

リフレッシュトークンは長く有効なので、いちばん大事に扱います。ログアウトのときには、Cognito にリフレッシュトークンを無効にするよう頼むこともできます。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 8 / 20
  • 3つのトークンと、それぞれの役目
  • 人
  • 鍵
  • 更新
  • ID トークン
  • アクセストークン
  • リフレッシュトークン
  • 誰か(名前・メール)。画面の表示用
  • API を呼ぶ許可。これを添える
  • 新しいトークンをもらう引換券
  • ID・アクセスの有効期間
  • 既定は1時間(5分〜1日で変更可)
  • リフレッシュの有効期間
  • 既定は30日(60分〜10年で変更可)
  • 短い入館証を頻繁に取り直す。盗まれても、使える時間が短くて済む
  • ひらめき
  • API に見せるのはアクセストークン。ID トークンは画面に名前を出すため。リフレッシュは取り直し用。

トークンの中身:JWT は「署名入りの手紙」

Cognito のトークン(ID とアクセス)は、JWT(JSON Web Token、ジョットとも読む)という形式です。JWT は、3つの部分を .(ドット)でつないだ1本の文字列です。

部分中身
1 ヘッダーどの方式・どの鍵(kid)で署名したか
2 中身(クレーム)誰か(sub)、いつまで有効か(exp)、どのアプリ宛てか、など
3 署名1と2を、Cognito だけが持つ秘密鍵で計算したもの

署名の仕組みを、手紙にたとえます。Cognito は、手紙(1と2)に、自分にしか押せない印鑑(秘密鍵での署名)を押します。印鑑の見本(公開鍵)は誰にでも配られています。受け取った人は、見本と照らせば「本当に Cognito が押したか」「押した後で書き換えられていないか」がわかります。1文字でも書き換えれば、印影と合わなくなります。

注意点が2つあります。

中身は暗号化されていません。 誰でも読めます。だから、パスワードや秘密の情報を入れてはいけません。

人を見分けるには `sub` を使います。 メールアドレスは利用者が変えられるので、DB のキーにすると、変えた瞬間に別人扱いになります。sub は利用者ごとに決まり、変わりません。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 9 / 20
  • トークンの中身:JWT は「署名入りの手紙」
  • ヘッダー
  • 中身(クレーム)
  • 署名
  • どの鍵で署名したか (kid)
  • "sub": "a1b2-…"
  • Cognito の秘密鍵で作る。 公開鍵で誰でも確かめられる
  • "exp": 1790000000
  • "client_id": "…"
  • 3つを「.」でつないだ文字列: xxxxx.yyyyy.zzzzz
  • ★中身は暗号化されていない。見られて困るもの(パスワードなど)は入れない
  • sub は利用者ごとに変わらない ID。メールアドレスは変わりうるので、DB のキーには sub を使う
  • ひらめき
  • 中身は誰でも読める。でも Cognito の秘密の鍵で署名してあるので、1文字でも書き換えれば偽物とわかる。

API での確かめ方:署名・期限・宛先の3つ

API がトークンを確かめるときは、図の4点をすべて見ます。

確かめること見るところ省くとどうなるか
署名Cognito の公開鍵で照らす誰かが作った偽のトークンで入れる
期限exp が今より後かずっと昔に盗まれたトークンで入れる
宛先クライアント ID が自分のものか同じユーザープールの、別のアプリ用のトークンで入れる
種類アクセストークンか(token_use)表示用の ID トークンで API を呼べてしまう

公開鍵は、Cognito がユーザープールごとに決まった URL で公開しています。この鍵の一覧を JWKS(JSON Web Key Set)と呼びます。API は一度取ってきて手元に置いておき、トークンのヘッダーにある kid に合う鍵で確かめます。

これらを自分で1つずつ書くのは、間違いのもとです。AWS が公開している aws-jwt-verify のような、専用のライブラリに任せましょう。4点をまとめて確かめ、公開鍵の取得と手元での保管もやってくれます(作り方のところでコードを見ます)。

後で見るように、API Gateway や ALB に、この確認そのものを任せることもできます。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 10 / 20
  • API での確かめ方:署名・期限・宛先の3つ
  • 鍵
  • Cognito
  • OK
  • 署名:Cognito の公開鍵で本物か
  • ユーザープール
  • OK
  • 期限:exp を過ぎていないか
  • ノートPC
  • OK
  • 宛先:自分のクライアントか
  • ブラウザ
  • 公開鍵
  • OK
  • 種類:アクセストークンか
  • サーバー
  • アプリ(API)
  • データベース
  • フォトログ
  • DB
  • 公開鍵は Cognito が決まった URL で公開している(JWKS)。API は一度取ってきて手元に置いておけばよい
  • 1つでも欠けると、別のアプリ用のトークンや期限切れのトークンで入れてしまう
  • ひらめき
  • 署名が本物か、期限内か、自分のアプリ宛てか。ライブラリに任せ、1つも省かない。

「Google でログイン」も、ユーザープールがまとめる

利用者の多くは、新しいパスワードを作るより、「Google でログイン」「Apple でサインイン」のほうを好みます。ユーザープールは、こうした外部の ID とつなぐことができます。

つなげる相手例
ソーシャルの IDGoogle、Apple、Facebook、Amazon
会社の ID 基盤SAML や OIDC という共通の決まりに対応したもの(社内の ID 管理システムなど)
Cognito 自身メールアドレスとパスワード

大事なのは、どこからログインしても、アプリが受け取るトークンは同じ形だということです。Google でログインした人も、パスワードでログインした人も、ユーザープールの中では1人の利用者として sub を持ち、同じ形の JWT が発行されます。

アプリは「この人がどの方法でログインしたか」を気にせず、いつもと同じように sub で人を見分ければよいのです。ログインの方法を後から増やしても、アプリのコードはほとんど変わりません。

Google などとつなぐには、それぞれの開発者向けの画面でフォトログを登録し、発行された ID と合言葉を Cognito に設定します。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 11 / 20
  • 「Google でログイン」も、ユーザープールがまとめる
  • インターネット
  • Google
  • スマホ
  • Apple
  • 鍵
  • ユーザープール
  • アプリ
  • 1人=1つの sub
  • 同じ形
  • サーバー
  • 違いを気にしない
  • 会社
  • 会社の ID
  • SAML・OIDC
  • メール
  • パスワード
  • メールで登録
  • ひらめき
  • Google・Apple・会社の ID とつなげる。どこから来ても、トークンは同じ形。

ID プール:ログインした人に、AWS の一時的な鍵を渡す

Cognito には、ユーザープールとは別に ID プール(アイデンティティプール)という機能があります。名前が似ていますが、役目はまったく違います。

ユーザープールID プール
役目「誰か」を確かめ、トークンを発行するトークンを、AWS を直接操作できる一時的な鍵と交換する
渡すものJWTIAM ロール(第3章)の一時的な認証情報
使う場面ほぼすべてのサービスアプリから S3 などの AWS のサービスを直接呼びたいとき

図の流れでは、スマホアプリが①ユーザープールでログインし、②そのトークンを ID プールに渡して、IAM ロールの一時的な鍵を受け取ります。③その鍵で、S3 の「自分のフォルダだけ」に写真を直接置きます。鍵は数時間で切れ、ロールの権限の範囲でしか使えません。

では、フォトログでも ID プールを使うべきでしょうか。答えは「使わない」です。第15章で、写真のアップロードには署名付き URLを使いました。API が「この1枚だけ、15分だけ置いてよい」という URL を発行する形です。こちらのほうが、何をどこに置けるかを API がきめ細かく決められます。

ID プールは、スマホアプリから AWS の複数のサービスを直接たくさん使うような場合に検討します。ログインしていないゲストにも、ごく限られた権限の鍵を渡すことができます。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 12 / 20
  • ID プール:ログインした人に、AWS の一時的な鍵を渡す
  • 鍵
  • ユーザープール
  • トークンを発行
  • ①
  • スマホ
  • フォルダ
  • S3
  • スマホ
  • 自分の場所だけ
  • ②
  • ③
  • 人々
  • ID プール
  • 盾
  • IAM ロール
  • トークン → 一時的な鍵
  • 第3章。数時間だけ有効
  • 名前が似ているが別物:ユーザープール=「誰か」を確かめる。ID プール=「AWS に触れる鍵」を渡す
  • フォトログは署名付き URL(第15章)で足りるので、ID プールは使わない
  • ひらめき
  • スマホから S3 に直接置きたいときなどに使う。トークンを、IAM ロールの一時的な鍵と交換する。

API Gateway・ALB に、トークンの確認を任せる

トークンの確認は、アプリの手前にある入口にも任せられます。

API Gateway(第22章) では、オーソライザーという「門番」を設定できます。HTTP API では JWT オーソライザー、REST API では Cognito 用のオーソライザーを使います。トークンが偽物や期限切れなら、API Gateway が 401(認証されていません、という応答)で断り、Lambda は起動すらしません。本物なら、トークンの中身(sub など)が Lambda に渡されます。無駄な起動が減るので、お金の面でも得です。

ALB(第11章) では、HTTPS のリスナーに「Cognito で認証する」という動作を足せます。ログインしていない人がやってくると、ALB が Cognito のログイン画面へ送り、ログインが済んでからサーバーへ転送します。ログインした人の情報は、x-amzn-oidc-data などのヘッダーでサーバーに届きます。

API GatewayALB
向いているものAPI(スマホアプリや、画面を JavaScript で作るサイト)画面をサーバーで作るサイト、管理画面、社内ツール
確認の仕方添えられたトークンを確かめるログインさせ、ALB がログインの状態を持つ
アプリの変更少ないほぼ不要

どちらを使っても、認可はアプリの仕事のままです。入口が教えてくれるのは「誰か」だけです。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 13 / 20
  • API Gateway・ALB に、トークンの確認を任せる
  • API Gateway(第22章)
  • ALB(第11章)
  • ネットワーク
  • API Gateway
  • 電気
  • ネットワーク
  • ALB
  • サーバー
  • JWT を確かめる
  • Lambda
  • HTTPS で認証
  • サーバー
  • ログインしていない人を Cognito の画面へ送る。 「誰か」はヘッダーでサーバーに届く。 管理画面・社内ツールを守るのに向く
  • NG
  • 401 で断る
  • HTTP API は JWT、 REST API は Cognito 用の オーソライザー
  • 偽物・期限切れ
  • どちらを使っても、アプリ側で「この写真を消してよいか」の認可は自分で行う
  • ひらめき
  • 入口で確かめれば、偽物のリクエストはアプリまで届かない。アプリは届いた「誰か」を信じて使える。

作り方:ユーザープールを作り、API で確かめる

コンソールで作る流れは次のとおりです。

手順操作気をつけること
1Cognito でユーザープールを作る。ログインに使うものに「メールアドレス」を選ぶログインに使うものと必須の項目は、後から変えられない
2アプリクライアントを作る。種類は Web のシングルページアプリ(シークレットなし)ブラウザのアプリに合言葉を持たせない
3コールバック URL(ログイン後に戻る先)と、ログイン画面のドメインを設定する本番の URL と開発用の URL を、必要なものだけ登録する
4API でアクセストークンを確かめる次のコード

API 側(Node.js)では、AWS が公開しているライブラリ aws-jwt-verify を使うと、図の右のように短く書けます。

ts
import { CognitoJwtVerifier } from "aws-jwt-verify";

const verifier = CognitoJwtVerifier.create({
  userPoolId: "ap-northeast-1_xxxx",
  tokenUse: "access",
  clientId: "xxxx",
});

// 偽物・期限切れ・別アプリ宛てなら例外になる
const payload = await verifier.verify(token);
const userId = payload.sub; // 利用者の変わらない ID

tokenUse と clientId を指定することで、先に見た「種類」と「宛先」も確かめられます。ユーザープールの ID やクライアント ID は秘密ではありませんが、環境ごとに違うので、設定として外から渡します。IaC(第18章)で作る場合も、作るものは「ユーザープール・アプリクライアント・ドメイン」の3つです。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 14 / 20
  • 作り方:ユーザープールを作り、API で確かめる
  • 人々
  • ユーザープールを作る(メールで入る)
  • import { CognitoJwtVerifier } from
  • "aws-jwt-verify";
  • const verifier = CognitoJwtVerifier.create({
  • ブラウザ
  • アプリクライアント(シークレットなし)
  • userPoolId: "ap-northeast-1_xxxx",
  • tokenUse: "access", clientId: "xxxx",
  • });
  • リンク
  • 戻り先 URL とドメインを設定
  • // 偽物・期限切れ・別アプリ宛てなら例外
  • const p = await verifier.verify(token);
  • p.sub // 利用者の変わらない ID
  • コード
  • API でアクセストークンを確かめる
  • ひらめき
  • コンソールで数ステップ。アプリ側は、公式のライブラリでトークンを確かめるだけ。

フォトログでは:パスワードを DB から消す

フォトログを Cognito に移すと、users 表は図のように変わります。

これまでこれから
人を見分けるキー自分で振った番号(id)Cognito の sub
パスワードハッシュにして保存持たない
メールアドレス保存Cognito が持つ。必要なら ID トークンから読む
名前・自己紹介など保存保存(サービス固有の情報はアプリが持つ)

写真やいいねの表は、users の sub とつなぎます。

すでに登録している利用者はどうするのでしょうか。全員に「パスワードを作り直してください」と頼むのは乱暴です。Cognito には、ログインのときに独自の処理を差し込む Lambda トリガーという仕組みがあり、その1つにユーザー移行のトリガーがあります。

順番起きること
1まだ Cognito にいない利用者が、いつものパスワードでログインする
2Cognito が移行用の Lambda を呼ぶ。Lambda は古い DB でパスワードを照らし合わせる
3合っていれば、その人を Cognito に登録する。次からは Cognito だけで確かめる

こうして、ログインした人から順に移っていきます。十分な期間がたったら、古いパスワードの列を消します。これで、フォトログの DB が漏れてもパスワードは漏れません。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 15 / 20
  • フォトログでは:パスワードを DB から消す
  • これまでの users 表
  • これからの users 表
  • id 12
  • sub a1b2-c3d4-…
  • email [email protected]
  • name あおい
  • password $2b$12$…
  • (パスワードは持たない)
  • name あおい
  • 移行:ユーザー移行の Lambda トリガーで、古いパスワードが合っていれば Cognito に登録し直す
  • 全員の移行が済んだら、古いパスワードの列を消す
  • ひらめき
  • users 表のキーを sub にし、パスワードの列を消す。移行はログインした人から順に。

お金:月に何人がログインしたか

Cognito のユーザープールの料金は、主に MAU(Monthly Active Users、その月にログインなどをした利用者の数)で決まります。登録しているだけで、その月に一度も来なかった人は数えません。

ユーザープールには3つのプランがあり、使える機能と単価が違います。

プラン主な中身
Lite基本のログイン。ログイン画面は旧来の簡素なもの
Essentials新しいマネージドログイン、パスキー、メールでの MFA など。新しく作るユーザープールの既定
PlusEssentials に加え、漏れたパスワードの使用や、いつもと違う場所からのログインを見つける機能

プランはあとから切り替えられます。Lite と Essentials には、毎月一定の MAU まで無料で使える枠があります(Plus にはありません)。単価と無料枠の大きさは、料金ページで確かめてください。

MAU とは別にかかるものもあります。

別にかかるもの内容
SMSMFA のコードを SMS で送ると、送った分の SMS 料金
メール既定の送り方は1日に送れる数に上限がある。本番では Amazon SES(メール送信のサービス)とつなぎ、SES の料金がかかる
  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 16 / 20
  • お金:月に何人がログインしたか
  • 人
  • 人々
  • 守られている
  • Lite
  • Essentials
  • Plus
  • 基本のログイン。旧来の画面
  • 新しい画面・パスキー。新規の既定
  • 漏れたパスワードの検知など
  • OK
  • Lite と Essentials には、毎月一定の MAU まで無料枠がある(Plus には無い)
  • NG
  • SMS でコードを送ると、SMS の送信料が別にかかる
  • NG
  • 既定のメール送信は1日の数に上限。本番は Amazon SES を使う
  • ひらめき
  • 課金の単位は月間アクティブユーザー(MAU)。プランで機能と単価が違う。無料枠もある。

よくある落とし穴

Cognito に任せても、使い方を間違えれば事故は起きます。

落とし穴何が起きるか防ぎ方
API に ID トークンを使う表示用のトークンで API が通る。宛先の確かめ方も変わってしまうAPI に添えるのはアクセストークン。tokenUse: "access" で確かめる
メールアドレスで人を見分けるメールを変えた人が別人扱いになる。同じメールで別の人が入れることもDB のキーは sub
トークンを雑にしまう画面に悪いスクリプトを埋め込まれる攻撃(XSS)で、JavaScript から読める場所のトークンを盗まれるXSS 対策をしっかりし、長く有効なリフレッシュトークンの置き場所を慎重に決める
後で変えられない設定ログインに使うもの(メールか、ユーザー名か)や必須の項目を変えたくなっても、作り直すしかない最初に決めてから作る。試しに作ったものをそのまま本番にしない
署名だけ確かめる期限切れや別アプリ宛てのトークンが通るライブラリで4点を確かめる
うっかり削除ユーザープールを消すと、名簿ごと消える。戻せない削除保護を有効にしておく

特に「後で変えられない設定」は、作り直すと利用者全員が登録し直しになります。本番用のユーザープールは、IaC(第18章)で設定を確かめてから作りましょう。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 17 / 20
  • よくある落とし穴
  • 人
  • API に ID トークンを使う
  • 書類
  • メールアドレスで人を見分ける
  • API に添えるのはアクセストークン
  • メールは変わる。キーは sub
  • コード
  • トークンを雑にしまう
  • 設定
  • 後で変えられない設定
  • XSS で盗まれうる場所に長く置く
  • ログイン方法・必須の属性
  • チェック
  • 署名だけ確かめる
  • NG
  • うっかり削除
  • 期限・宛先・種類も見る
  • 削除保護を有効にしておく
  • ひらめき
  • Cognito に任せても、トークンの扱いを間違えれば同じ事故が起きる。作り直しが要る設定もある。

いつ Cognito を選ぶか

Cognito は、「AWS の上で、自分のサービスの利用者を持つ」ときの第一候補です。

Cognito が向くほかを考える
一般の利用者がいる Web・スマホのサービス社員が AWS を操作するためのログイン(第1章の IAM Identity Center)
API Gateway・ALB とそのまま組みたいサーバー同士の呼び出し(IAM ロール。第3章)
ソーシャルログインや MFA を早く付けたい会社がすでに別の ID 基盤を全社で使っている
料金を利用者の数に合わせたいログインの画面や流れを、細部まで自由に作り込みたい

AWS の外にも、Auth0 や Firebase Authentication のような、ログインを借りるサービスがあります。どれを選んでも構いません。大事なのは、パスワードの保管や本人確認を自作しないことです。

判断の問いは、「このログインの利用者は、誰か」です。サービスの利用者なら Cognito(またはそれに類するサービス)、AWS を操作する社員なら IAM Identity Center、プログラムなら IAM ロールです。この3つを混ぜないことが、守りの基本になります。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 18 / 20
  • いつ Cognito を選ぶか
  • Cognito が向く
  • ほかを考える
  • OK
  • 一般の利用者がいる Web・スマホのサービス
  • NG
  • 社員の AWS 操作(→ 第1章)
  • OK
  • API Gateway・ALB と組みたい
  • NG
  • サーバー同士の呼び出し(→ IAM ロール)
  • OK
  • ソーシャルログインや MFA を早く付けたい
  • NG
  • 会社がすでに別の ID 基盤を使っている
  • OK
  • 料金を利用者数に合わせたい
  • NG
  • ログイン画面を細部まで作り込みたい
  • Auth0・Firebase Authentication など、AWS の外の選択肢もある。どれを選んでも「自作しない」が大事
  • ひらめき
  • AWS の上で、自分のサービスの利用者を持つなら第一候補。社員が AWS を操作するログインとは別物。

片付け:ドメイン → 削除保護 → プール

練習で作ったユーザープールを消すときは、順番があります。

順番やること理由
1ログイン画面のドメインを削除するドメインが付いたままでは、ユーザープールを削除できない
2削除保護を無効にする有効なままでは削除できない
3ユーザープールを削除する名簿もすべて消える

CLI では次のようになります(ID とドメインは自分のものに置き換えます)。

bash
aws cognito-idp delete-user-pool-domain --domain photolog-xxxx --user-pool-id ap-northeast-1_xxxx
aws cognito-idp delete-user-pool --user-pool-id ap-northeast-1_xxxx

削除保護を無効にするのは、コンソールのユーザープールの設定から行えます。

ユーザー移行のために作った Lambda や、Google などの外部サービスに登録したアプリの設定も、練習用なら一緒に消しておきます。

本番のユーザープールを消すと、利用者は全員ログインできなくなり、元に戻す方法はありません。 削除保護は、本番では必ず有効にしておきましょう。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 19 / 20
  • 片付け:ドメイン → 削除保護 → プール
  • インターネット
  • ドメインを削除
  • 開いた錠
  • 削除保護を無効に
  • バツ
  • ユーザープールを削除
  • ログイン画面の住所
  • 設定で切り替える
  • 名簿もすべて消える
  • aws cognito-idp delete-user-pool-domain --domain photolog-xxxx --user-pool-id ap-northeast-1_xxxx
  • aws cognito-idp delete-user-pool --user-pool-id ap-northeast-1_xxxx
  • ★本番のユーザープールを消すと、利用者は全員ログインできなくなる。元に戻す方法は無い
  • ひらめき
  • ユーザープールは、ドメインが付いていたり削除保護が有効だったりすると消せない。順番に外す。

まとめ:ログインは借りて、トークンを正しく確かめる

この章で学んだことをまとめます。

項目内容
なぜ借りるかパスワードの保管・MFA・再設定・ソーシャルログイン…安全に作り続けるのは大仕事
ユーザープール利用者の名簿とログインの窓口。パスワードはここにだけある
認証と認可「誰か」は Cognito、「何をしてよいか」はアプリ
トークンID(表示用)・アクセス(API 用)・リフレッシュ(取り直し用)。JWT は署名入りの手紙
確かめ方署名・期限・宛先・種類の4点。ライブラリに任せる
連携API Gateway・ALB に確認を任せられる
ID プールAWS の一時的な鍵が要るときだけ

フォトログは、パスワードを持たないサービスになりました。ところが、利用者が増えるにつれて、別の不安が見えてきます。

ログを見ると、ログイン画面や API に、同じ IP アドレスから1秒に何百回もリクエストが来ています。よくある攻撃の文字列を埋め込んだリクエストも混ざっています。さらに先週、誰かが S3 の設定を変えたようなのですが、誰が、いつ、何を変えたのかがわかりません。

次の第27章では、入口・中・記録の各所に守りを重ねる多層防御を学び、フォトログの守りを固めます。

  • AWS でサービスを作る 26 ― ログイン:Cognito
  • 20 / 20
  • まとめ:ログインは借りて、トークンを正しく確かめる
  • なぜ借りるか
  • パスワード・MFA・再設定・ソーシャル…安全に作り続けるのは大仕事
  • ユーザープール
  • 利用者の名簿とログインの窓口。パスワードはここにだけある
  • トークン
  • ID(表示用)・アクセス(API 用)・リフレッシュ(取り直し用)
  • 確かめ方
  • 署名・期限・宛先・種類。ライブラリに任せる
  • 連携
  • API Gateway・ALB に確認を任せられる
  • ID プール
  • AWS の一時的な鍵が要るときだけ
  • 守られている
  • 次の困りごと:攻撃のリクエストと、誰が何をしたかわからない不安
  • ひらめき
  • 次の第27章:入口に怪しいリクエストが押し寄せ、誰が設定を変えたかもわからない。守りを重ねる。

0 件のコメント

読み込み中…

権利侵害・不適切な内容の連絡: [email protected]