🖥

OAuth本を読んだ 軽いまとめ ( O'REILLY | Getting Started with OAuth 2.0 )

2023/08/26に公開

社内勉強会に向けて勉強した。
これを読んだまとめ。

image

  • 紙の本だと80ページぐらい。
  • コードサンプルはPHPで書かれている。

読んだ動機

  • 前から気になっていたから。 OAuth がどうやって動いているのか。アプリケーションとどういうふうに連動しているのか。
  • OAuthを使うアプリケーションを、プライベートで作ってみたいと思っているから。
  • Oauth をうまく扱ってくれるモジュール等のおかげで、具体的な認証プロセスをあまり意識することが、あまりないから。
  • 日頃から個人的にも、色々なサービスで OAuth のお世話になっているから。

OAuth 登場によってなにが変わったか

  • 開発者たちの頭痛がやわらいだ。なぜなら100個ものAPIをひとつの技術で扱えるようになったから。(これが一番良いところ)

OAuth の歴史

  • Google Calender API が最初にリリースされた頃、ユーザーがアプリケーションに権限を委譲する方法は、「ユーザー名」と「パスワード」を渡すしかなかった。
  • その後、Google による AuthSub / Yahoo! による BBAuth などの認証方法が生まれたが、今度はアプリケーション開発者のコストが上がることになってしまった。アプリケーション開発者たちは、複数のAPIについて学習して、その一式をアプリケーションに組み込まなければいけなかった。(パスワード方式に比べると、かなり面倒ですね)
  • さらにその後、まったく新しいAPIを作ろうする人たちも、自分たち独自の認証方式なんか揃えたくなかった。このような状況から、主要APIのプロバイダとスタートアップは「ウェブベースで共通の認証方法」を作ることに決めた。

なぜユーザー名とパスワードではダメなのか?

1. 信頼性

そもそもユーザーは、第三者のアプリケーションにパスワードを提供したくないだろう。

2. ユーザーのウェブリテラシーを下げる

もしユーザーが、アプリケーションに喜んでパスワードを提供したとしても。
それは長期的に考えると、他のフィッシング詐欺がはびこる下地になる。

3. 行き過ぎたアクセス権

アプリケーションは必要なデータだけではなく、すべての権限にアクセス出来てしまう。

4. 頼りにならない

ユーザーがパスワードを変えると、アプリケーションはデータにアクセス出来なくなってしまう。

5. 権限取り消しの問題

ユーザーはアプリケーションへのアクセス権を取り消すために、パスワードを変更するしか手段がない。
けれどパスワードを変更したら、ユーザーが他に連携してるアプリケーションも、同時に使えなくなってしまう。

6. 強力な認証を使えない

たとえばログインのためにキャプチャ画面を出すとか、ワンタイムパスワードを使うとか。
より強固な認証方法が使えない。

Oauth の登場人物

  • Resouce owner (ユーザー)
  • User Agent (ユーザー端末)
  • Client (アプリケーション)
  • Autorization server ( API - Facebook とか Google とか)

この中で、Resource Owner をのぞいた三者がやり取りをします。
( Resource Owner は「ユーザー」等を示すものなので、技術的なプロセスには関わっていません )

ここでは便宜的に、それぞれ「ユーザー(ユーザー端末)」「アプリケーション」「API」と呼ぶことにします。

サーバーサイド アプリケーション

フロー

  • ユーザーはまず、アプリケーションから API にリダイレクトされる。
  • ユーザーは Authorization code を持って、アプリケーションに帰ってくる。
  • アプリケーションはユーザーから Authorization code を得る。これをAPIに問い合わせて、アクセストークンを得る。

この方法だと、アクセストークンはユーザー端末(ブラウザ)には現れない。ここがセキュリティ的に良いところ(たぶん)。

ユーザーをAPIに送る

client_id

APIがアプリケーションに発行したID。これは固定。

redirect_uri

APIでユーザーがアクセスを許可した時に、アプリケーションに戻ってくるURL。
この redirect_uri で指定したページに、アクセストークンを受け取る処理とかを、いろいろ書けば良い。

scope

アクセスしたいデータのタイプを記述する。
たとえば「Google Docsにアクセスしたい」というのであれば、それをここに記述する。

state

CSRF 攻撃を防ぐためのランダムな文字列。
こんな感じ ( rand(999_9999) ) で適当なものを生成して渡してやれば良い。

これは使い捨てなので「リクエスト」があるたびに、新しいものを生成して渡す必要がある。

URL

実際にはこんな感じになる。

http://www.googleapis.com/auth/tasks/?client_id=xxx&redirect_uri=yyy ...

アプリケーションがアクセストークンを得る

code

ユーザーがAPIから「もらって」きた Authorization code。
アプリケーションはこれを元に、アクセストークンを得る必要がある。

state

「ユーザーをAPIに送る時」に渡したランダムな文字列が、再び返ってくる。
もし両者が一致しなければ、第三者による何らかの攻撃であると考えられる。ここでもセキュリティ対策が出来るようになっている。

アクセストークンを得る

アプリケーションからAPIに問い合わせをおこなう。

Basic認証の「ユーザー名」に client_id を。「パスワード」に client_secret を渡す方法が OAuth 2.0 では最新の方法だ。
だが多くのAPIプロバイダはまだこの方法をサポートしていない。

そのかわりに HTTP POST リクエストを使う方法がある。

  • client_id
  • client_secret
  • access_token
  • token_type
  • expire_in
  • refresh_token

その他

アクセストークンは多くの場合、アプリケーションのデータベースに保存される。が、そう取り決められているわけではない。
アクセストークンをサーバーセッションに記録しておけば、パフォーマンス的に良い感じ。

他に書きたかったこと (時間切れ)

  • 認可と認証の違い。認可について。
  • エンドポイントとは。
  • OAuth 1.0 との違い。
  • リフレッシュトークンの仕様。

余談

  • オライリーの本はやや格調高いイメージがあったが、この本は非常に読みやすかった。原文だから読みやすいのか、それとも本自体が読みやすいものなのかは不明。おそらくオライリーの中でも易しい部類。ちなみに日本語版は出ていない様子。
  • オライリーの良いところは、初学者がつまづいたり、疑問に思う「盲点」をよく理解していて、その概念的な回答をくれる本が多いことだと、改めて感じた。「理解する」という意味では、安くて薄い本を買うより、むしろずっと易しい。

チャットメンバー募集

何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ

Twitter

https://twitter.com/YumaInaura

公開日時

2016-06-30

Discussion