自分の理解のために OAuth2.0 での認可を Zenn の Google ログインで説明してみる
登場人物
Provider
Google や Twitter など、ユーザーに関する情報を持っているウェブサイト。
Consumer
Provider の情報を使ってアレコレするサイト。
あなたが OAuth 認証認可を使って何かウェブサイトを作りたい時、作るサイトは Consumer となります。zenn.dev
も Google ログインに対応しているので Consumer です。
User
すでに Provider に情報を登録していて、Consumer のサイトをこれから使おうとしている人。
Client
User の操作側のプログラム。
OAuth 2.0
手順は以下の通り。
-
Client が Consumer(Zenn) に、「これから OAuth を使いたい」という情報を伝えます(例えば Login with Google というボタンをクリックします)。
-
Consumer(Zenn) は、User の情報がどの程度欲しいか(権限がどれくらい必要か)を表す
scopes
を決めます。また、同時にstate
というランダムトークンを作ります。そして、Provider(Google) への URL を、scopes
、state
、 そして Consumer が誰かを表すclient id
を埋め込んだ状態で Client に渡します。 -
Client は、渡された URL を使って Provider(Google) にアクセスします(例えば Login with Google をクリックした後に出てくる Google の画面の URL は、前のステップで Consumer から渡された URL です)。
この URL に埋め込まれたclient id
を見て、Provider(Google) は Consumer(Zenn) を判別します。OAuth を使ってアプリを作る場合、Consumer(Zenn) 側が事前に OAuth 認証を使うために Provider(Google) に登録しているので、判別できます(例えば Google であれば Google Developer Console で登録します)。
また、URL に埋め込まれたscopes
を見て、Consumer(Zenn) がどのような権限を欲しているかを確認します。Provider(Google) はそれをもとに「この Consumer(Zenn) というサイトは以下のような権限を求めていますよ」という確認画面を出します。 -
User 側が、ログインしたり OK ボタンを押したりして同意したのを確認したら、Provider(Google) は
authorization code
を発行します。そして今度は Consumer(Zenn) への URL を、authorization code
とstate
を埋め込んだ状態で Client に渡します。 -
Client は、渡された URL を使って Consumer(Zenn) にアクセスします。Consumer(Zenn) はまずこの URL に埋め込まれた
state
トークンを見て、それが以前に自分が発行したものと同じかどうかを確認します。これにより、悪意のある別のユーザーが元の User を騙ることを防ぎます。
それから、Consumer(Zenn) は URL に埋め込まれたauthorization code
を、自身のclient id
とともに Provider(Google) に POST で送ります。Provider(Google) 側は、自分が以前に発行したauthorization code
に間違いないことを確認します。そして、最終的に Consumer(Zenn) にaccess token
を返します。これで、全てのプロセスが完了します。
Consumer(Zenn) はaccess token
を持っていれば User が「ログイン済」であると判断し、ログイン後のページを返す処理を行うことができます。
用語の整理
-
client id
: Consumer(Zenn) が Provider(Google) に、自分が誰なのかを伝えるためのもの -
scope
: Consumer(Zenn) が、自分のアプリにユーザーの情報がどのくらい必要なのかを考えて設定するもの -
state
: Consumer(Zenn) が、悪意のあるユーザーによる乗っ取り(CSRF攻撃)を防ぐために用意するもの -
authorization code
: Provider(Google) が Consumer(Zenn) の正当性を確認するために発行するもの -
access token
: ユーザーが認可済みであることを Consumer(Zenn) が確認するためのもの(Provider(Google) が発行する)
認証と認可の違いについて
認証(Authentication)は「誰であるか」を確認することで、認可(Authorization)は権限を与えることです。
OAuth でログインするというのは、あるユーザーの認可済み access token
の存在をもってして、あるユーザーの認証も行うということです。なので、認証認可とまとめて呼ばれたりもします。
ですが、OAuth 自体は元々認可をするために作られたプロトコルなので、それを認証にも使ってしまうことは潜在的には危険です。実際、悪質なサイトがあるユーザーの access token
を流出させたりすると、他の OAuth を認証に使っているサイトでもそのユーザーとして認証できていることになってしまいます。
Reference
Discussion
ちょっと気になったんですが
と、読者が混乱しそうな内容になっているように思えます。
アクセストークン取得までの流れを説明したい場合は、Googleログインの例を使ったとしても「この時点でアクセストークンを取得できます」「アプリケーションはユーザーの代わりにAPIアクセスできます」までで留めておくのが良さそうです。
その上で、認証用途に利用する場合は
という流れにすると、うまく機能を整理しながら説明できるかもしれません。
はい、おっしゃる通り、体系だった説明にはなっておりません。あくまで自分の理解のためにまとめたものです。
記事タイトルが啓蒙っぽい感じでミスリーディングだったので、変更しておきました。
(この記事を書いた時には存在に気づかなかったのですが、スクラップを使った方が良かったなぁと思っています。)