【図で解説】非エンジニアでもわかるOAuth 2.0|ややこしさの正体は“歴史”にアリ!

OAUTH2.0を歴史的背景をもとに非エンジニアにも分かりやすく解説
はな子

OAuthってなに?認証に使えるんだよね?

ChatGPT

OAuthとは「権限」の仕様のことです。「認証」は含みません。

はな子

そ、そうなんだ、わかった。OAuthは「権限」だけ考えればいいんだね!

どこかのシステム

うちのAPI、OAuth2.0認証に対応してるんでー

はな子

さっき、OAuthは「権限」だけって聞いたよ!?どういうこと!?

この矛盾、多くの方が一度は感じたことがあるのではないでしょうか?エンジニアでさえ、この本質を話せる人は一握りだと思います。

この問題、OAuthの歴史や闇を理解しないとうまく説明ができません。そして、この闇を理解したら傍観者の眼差しでAOuthの話を見下ろせるでしょう。

今回の主役はずばり「OAuth」。やつの矛盾にメスを入れて、原因を一つ一つ明らかにしていきたいと思います。

非エンジニアの方でも、分かりやすく解説しますので、ぜひ、最後まで読んでいただいて世のエンジニアたちを傍観者の椅子から眺めていただければと思います。

それでは、まずはOAuthの矛盾の原因を見ていきましょう。

矛盾の原因

矛盾の原因を一つひとつ分解していった結果、行き着いたのは、次の3つのポイントでした。

原因1.OAuth2.0は本当に矛盾していた
原因2.OAuth2.0には別の顔があった
原因3.OAuth2.0が矛盾を抱えたままOIDCが登場してより混乱 ←今ここ

ひとつずつ見ていきます!

第1章:OAuth2.0は本当に矛盾していた

「OAuthは、頭のイかれた超天才が考えたものだから、自分には一生理解できない──」
かつての私は、本気でそう思っていました。

でも実際は、OAuthがシンプルに矛盾だらけであることに気づいてしまったのです。

OAuthは本当に矛盾していた!OAuthの暗黒歴史

OAuthは2007年、Twitterに在籍していたBlaine Cook(ブレイン・クック)氏らが中心となって策定、公開されました。

当時は、FacebookやTwitterが誕生したSNS爆誕期。世の中を見渡してみると、まだ認証や認可の標準仕様が整っておらず、各社が自由に実装していました。かろうじてOpenIDがありましたが、仕様が特殊すぎて敬遠されていました。

そんな中、Twitter社はAPIの開発に力を入れ始めます。安全にユーザーの個人情報へアクセスする方法を模索する中で、OAuthが誕生へとつながります。

解説

API・・・Application Programming Interface(アプリケーション・プログラミング・インターフェース)の略。ソフトウェア同士が機能やデータをやり取りするための「ルール」や「窓口」のこと

ある日、創始者のクック氏はこんなことを考えていました(想像)。

「IDとパスワードのやりとりは危険で古臭い。もっと良い方法はないか?」

そこでひらめきます。
「そうだ!許可だけ渡せばいいんだ!この仕組みを世界標準にして、TwitterのAPIをみんなに使ってもらおう!」(誇張表現あり)

こうして、OAuthは誕生しました。

しかし仕様が複雑だったため、なかなか正しく理解できるエンジニアは少数。気づけば世界中のエンジニアたちは、自社システムでOAuthを認可だけでなく認証にも使うように。つまり、勝手に仕様を魔改造してしまったのです。

そこから長い暗黒時代が始まりました。

魔改造のOAuthとは?

「魔改造のOAuth」とは何か?気になりますよね。まずは、本当のOAuthの画面の流れを見てみましょう。

本当のOAuthのイメージ

ここでは、あるアプリがTwitterの最新投稿を読み込むケースを例に説明します。

まずは正しいOAuthの流れから。ここでは、とあるアプリにTwitterの最新の投稿を読み込むケースを例にしています。

前提として、CさんはすでにTwitterにログイン済みです。

Cさんがアプリの取り込み画面を開き、「あなたのツイートを取り込もう!」をクリック。
すると、OAuthの認可画面が表示され、「はい」をクリックすると、アプリはTwitterの自分の情報にアクセスする許可を得ます。

その結果、アプリはCさんのTwitter最新投稿を取得し、アプリ内に埋め込むことに成功しました。

つまり、ログインIDやパスワードを使わずに認可だけを得ることに成功し、まさにBlaine Cook氏の狙い通りの仕組みなのです。

めでたし、めでたし……

とはなりません。
現実はBlaine Cook氏の思惑とは異なる方向に進んでいきます。

魔改造のOAuthのイメージ

それでは、次に「魔改造OAuth」の流れを一緒に見ていきましょう。

今回は、通販サイトにCさんのTwitterアカウントでログインするケースです。

前提として、CさんはすでにTwitterにログイン済みです。

その状態で通販サイトのログイン画面にある「Twitterのアカウントでログイン」をクリック。
するとTwitterからアクセス権限の許可を求められ、Cさんは「許可」をクリックします。

すると通販サイトはCさんのTwitterの個人情報をさまざま取得でき、これを使って通販サイト側でログイン状態を作ります。

つまり、OAuth2.0を使ってログインできるように魔改造しちゃったんですね。

こんな使い方がエンジニアコミュニティで共有され、世界中に広がっていきました。
その結果、そこからしばらくの間OAuth2.0は、事実上「認証」にも使われ続けることになります。OIDCが登場するまでは。

これが、OAuth認証という矛盾した言葉が定着してしまった経緯です。OIDCが登場した今でも、この誤った仕様のままのサイトが多く存在すると言われています。

第2章:OAuth2.0には2つの顔があった!

OAuth 2.0には、実は2つの顔があります。
このことを知らないと、話がかみ合わなくなってしまい、結構致命的です。

1つ目の顔

1つ目の顔は、OAuthの王道ともいえる「ユーザーの認可」。
ユーザーが画面で『はい』か『いいえ』を選ぶあのフローですね。

2つ目の顔

2つ目の顔は、「APIの認可」です。
たとえば、「Twitter全体の人気ハッシュタグを取得するAPI」。これは誰でも取得できていいのでユーザーの認可を必要としませんよね。
ただし、APIを呼び出すアプリは、TwitterからAPIを呼ぶ許可を得ている必要があります。

この2つの違いは、OAuth 2.0の仕様にも明確に記載されていますので、ここから深掘りして説明していきます。

OAuth2.0の4つの認可フロー

OAuth 2.0の認可フローには、仕様上こちらの4つの種類があります。

ただし、そのうち真ん中の2つは現在非推奨となっているため、ここでは割愛します。
つまり、実質的には2つのフローがメインです。

1つ目の顔が「認可コードフロー(Authorization Code Flow)」、
2つ目の顔が「クライアントクレデンシャルフロー(Client Credentials Flow)」というわけです。

これ、意外と知らない人が多いので、もしそういう人を見つけたらクールに教えてあげましょう。
実はこれも、OAuthがもやもやする原因のひとつになっています。

APIの認可がOAuthにあるって違和感、ありませんか?

ここでなにか腑に落ちないあなた・・・その感覚、めちゃくちゃ正しいです!

OAuthはもともとユーザーに権限を付与するために生まれました。でもOAuth 2.0では、ユーザーが関わらないAPI同士の通信(API認可)の仕組みが追加されてしまったんです。つまり、OAuthの範囲が広がっちゃったんですね。

この理由は見つけられなかったので、ChatGPTさんに聞いてみました(なので、ゆる〜く受け止めてくださいね笑)

Q. なんで、APIの認可の仕様がOAuth2.0に追加されちゃったの?

✅ 実務上、必要だったから。

  • バックエンド同士(API to API、マイクロサービス間)でセキュアに通信する仕組みが必要だった。
  • ベーシック認証やAPIキーより、トークンベースの認証の方が安全でモダン。
  • OAuthの仕組みを流用すれば、既存の認可サーバーを再利用できて便利

なんだか、理由も的を得ていませんが大人の事情みたいなのもあったんでしょうね。

さらに、こんなことも聞いてみました。

| 設計者たちも「OAuthっぽくない」と思ってた?

はい、実際そうです。
OAuthの初期設計者である Eran Hammer 氏はこう語ってます:
"Client Credentials Flow is just a secure way to authenticate a system to another system.
It's technically part of OAuth 2.0, but philosophically it's not OAuth."
(訳)クライアント・クレデンシャル・フローは技術的にはOAuth 2.0の一部だけど、思想的にはOAuthじゃない。

当事者たちも悩み抜いた末の決断だったのかもしれませんね…💧

認可ってみんなが知ってる「あれ」のこと

ちょっと話がそれますが、もし「認可って具体的に何?」と聞かれたら、あなたはどう答えますか?わかりやすい答えの一つはこうです。

「〇〇にアクセス権限を与えてもいいですか?って聞かれる画面のことだよ」

そう、この画面こそが「認可の画面」。つまり、「OAuthと言えばこの画面」と言っても過言ではありません。

これを覚えておくだけで、OAuthの理解がかなりスッキリしないでしょうか?

もちろん、これは1つ目の顔(ユーザーの認可4)の場合で、2つ目の顔(API間通信)の場合は、この画面は出ませんからね!

第3章:OAuth2.0が矛盾を抱えたままOIDCが登場!

OAuth2.0の混乱と暗黒時代に光を差すべく登場したのがOIDC(OpenID Connect)でした。しかし、現場ではまだまだOAuth魔改造認証全盛期。
一度おかしくなった仕様を元に戻すのは簡単ではありませんでしたが、少しずつ真実に気づく人たちが増えていきます。

ここで、OIDCについて改めておさらいしましょう。

OIDC(OpenID Connect) とは

OIDCとは、OAuth2.0の認可の仕組みをベースに「認証」を追加した新しい仕様です。
言い換えれば、OAuth2.0の認可フローを利用しながら、ユーザーが「誰か」を確認できる仕組み。
そのため、OIDCはシングルサインオン(SSO)の標準仕様としても広く使われています。

OAuth1.0が誕生したのは2007年、OIDCの登場は2014年と、約7年の歳月を経てようやく認証の標準仕様が明文化されました。

ただし、OIDCが認証を担う一方で、ユーザーの認可は引き続きOAuth2.0の役割です。つまり、OIDCが登場してもOAuth2.0自体はなくなりません。OAuth認証がなくなっただけ。

大きく変わった!OIDCの環境とは?

OAuthとOIDCの違いのひとつに、必要なシステム構成の違いがあります。

OAuthでは、「認可サーバー」だけを用意すればユーザーに権限を与えることができました。しかしOIDCになると、ユーザーそのものを管理・認証するための**IDプロバイダ(IdP)**が必須になります。

しかも、多くのIdPはOAuth 2.0の認可サーバーの役割も一緒に担ってくれるため、OIDCではIdPを1つ用意すれば両方まかなえるのが特徴です。

解説

IdP・・・Identity Provider(アイデンティティ・プロバイダ)とは、ユーザー管理・本人確認を代行してくれる外部のサーバーやサービスのこと

OAuth 2.0OIDC
認可サーバー◎必須◎必須(IdPに含まれることが多い)
IDプロバイダ(IdP)✕不要◎必須

表にするとこんな感じです。

OIDCではIdP(アイディーピー)を用意しないといけませんが、その代わりに別途で認可サーバーを用意する必要は基本的にありません。IdPがその役割を兼ねていることがほとんどです。

ちなみに、IdPとして使える代表的なサービスには以下のようなものがあります:

  • クラウド系:AWS Cognito、Azure AD、Google Identity、Auth0、Okta、OneLogin、Ping Identity
  • OSS系:Keycloak、Gluu、Dex
  • 日本のID連携系:LINE Login、Yahoo! JAPAN ID、楽天ID など

OIDCが登場して画面はどう変わった?

では、OIDCが登場すると、あの“魔改造OAuth”たちはどう変わったのでしょうか?比較してみましょう。

…あれ?見た目は、魔改造OAuthとほとんど変わらない気がしますよね。

実は、IdPには権限を設定する機能があるのです。この権限を設定しておけば、実装次第で認可の画面をスキップできるのです。

ただし、権限を設定するだけでは不十分で、アプリ側にもそれに合わせた実装が必要なんですけどね(このあたりは、IdPの権限の仕様に大きく依存する)

よって、どのIdPを使うかはかなり重要なポイントになります。

OIDCにも認可フローが登場して混乱の渦に!

OIDC(OpenID Connect)の登場で、「OAuthを認証に使っていた問題」は解決に向かいました。しかし、舞台に新たなプレイヤーが現れたことで、現場はまたしても混乱の渦に――。

というのも、OIDCにも「認可フロー」があるのです。

OAuth2.0とOIDCの認可フローを比べてみましょう。

この図の違いを理解することで、それぞれの役割――OAuth2.0は何を担当し、OIDCは何を補完しているのか――が見えてきます。

まず、OAuth2.0には「Authorization Code Flow」という代表的なフローがあります。これは、前出の“認可画面”が表示されるタイプですね。

一方、OIDCにもまったく同じ名前の「Authorization Code Flow」が存在します。

こちらは、主に認証つまりシングルサインオン(SSO)のフローのことをさします。ただ、それだとOIDCは「認可フロー」じゃなくて「認証フロー」だろ!と突っ込みたくなりますが、認可も一部あるらしいので…。

まとめると、「Authorization Code Flow」という言葉には、

  • OAuth2.0における“認可専用のフロー”
  • OIDCにおける“認可+認証のフロー”

という2つの意味が存在するのです。

・・・ややこしいですよね💧

この違いを理解していないと、説明が噛み合わなかったり、設計で迷子になったりしがちなので、ぜひここで頭に入れておいてくださいね!

まとめ:OIDCとOAuth2.0の今後の棲み分け

最後に、OIDCとOAuth2.0の今後の棲み分けについて整理して終わりにしたいと思います。

OAuth 2.0OIDC備考
ログイン
Authorization Code Flow

OIDCはid_tokenで認証。OAuthは認証の仕様を定義していない
SSO
Authorization Code Flow
OIDCはIdPを通じてSSO実現可。OAuth単体ではできない
API通信
(マシン間)

Client Credntial Flow
OAuthのClient Credentials Flowはマシン間通信向き
従来の認可
(アクセスしていいですか?)

Authorization Code Flow
OAuth 2.0の主目的は認可。OIDCは認証寄りなので✕
新しい認可
(IdPで権限を管理)

Authorization Code Flow
OIDCはSCOPEなどにより権限情報を渡せるが、認可判断はアプリ側

OAuth2.0は、認証を伴わない従来の「認可」フローと、API間通信(システム対システムの認可)の2つの役割を担い、今後も使われ続けます。

一方で、OIDCはログインやシングルサインオン(SSO)などの認証基盤として、ますます普及していくでしょう。

このように、OIDCの登場によって、OIDCとOAuth2.0はそれぞれの役割で明確にすみわけができるようになりました。


さいごに

以上、**「OAuth 2.0は本当に矛盾していたのか?」「OAuth 2.0には別の顔があった?」「OIDCの登場でさらなる混乱?」**といった視点から、OAuth 2.0の本質やその限界、そしてOIDCとの関係について解説してきました。

少しでも、あなたの理解の手助けになっていれば嬉しいです!ここまでお読みいただき誠にありがとうございました。

※もし記載に誤りや不明点があれば、ぜひコメント欄からご指摘いただけると助かります。