OAuth 2.0の理解を諦めた人へ:絶対に理解させるガイド
背景
OAuth 2.0 は、現代の Web およびモバイルアプリケーションで認証と認可のために広く採用されているプロトコルです。多くの開発者が最初にこのプロトコルに直面すると、その概念やフローの多様性に圧倒されることがある。特に、セキュリティが重要な役割を果たすアプリケーションでは、OAuth 2.0 の正確な理解と適切な実装が必須となる。
この記事では、特に Auth0 を使用して OAuth 2.0 を実装しているエンジニア向けに、OAuth 2.0 の基本から応用までをわかりやすく解説します。Auth0 は、OAuth 2.0 プロトコルをサポートすることで、開発者がセキュアな認証を簡単に実装できるようにするサービスの一つです。これにより、エンジニアは認証機能のコンプレックスさを抑えつつ、安全なアプリケーション開発に集中できるようになる
本ガイドでは、OAuth 2.0 の主要なコンセプト、利用シナリオ、そして Auth0 と組み合わせた実践的な実装例を通じて、読者が OAuth 2.0 の全体像をしっかりと掴めるように構成しています。OAuth 2.0 の理解が進むことで、より効率的かつ安全に認証システムを設計・実装できるようになるでしょう。
基礎知識
OAuth2.0 とは
OAuth 2.0 は、第三者アプリケーションがユーザーの代わりにサーバー資源にアクセスするための権限を安全に委任するためのシステムです。
(あくまでリソースアクセス許可の権限のみです。「誰が」「いつ」「どこで」「なんのために」といった情報 かつ署名されていると OpenID Connect になります
)
auth0
Auth0 は、開発者が認証と認可機能をアプリケーションに容易に統合できるようにするクラウドベースのサービスです。
他の例:
- cognito(AWS)
- Firebase Authentication (Google)
- Okta
ただ、利用者数や機能によって料金がかかることや柔軟で機能追加ができないため、大規模な会社では、自作の認証サーバがある印象です。
accessToken
AccessToken は、OAuth 2.0 認証プロセスでクライアントがリソースサーバーのリソースにアクセスするために使用されるトークンです. frontend から backend に アクセスするための鍵ぐらいに思ってくれたらいいです。(後で詳しく説明します)
refreshToken
refreshToken は、AccessToken が失効した後に新しい AccessToken を取得するために使用されるトークンです。
(後で詳しく説明します)
解説
流れとしては、
- accessToken の問題を解決するために refreshToken があり
- refrehToken の問題を解決するために refresh Rotation がある
なぜ accessToken が必要なのか
1. accessToken で backend にアクセスする
2. accessToken が盗まれると...
backend にアクセスするごとに accessToken
がインターネット上を通るので盗まれる可能性がある。accessToken
が盗まれることで悪役は、backend の api にアクセスが可能になってしまう.
大きな問題点としては、同じ accessToken が使われていることである
なぜ refreshToken が必要なのか
1. refreshToken を使うと
refreshToken
を認証サーバに渡すことで新しい accessToken
を取得することができる
2. accessToken を盗まれると...
refreshToken
を使うことで、accessToken
が更新される。これにより、accessToken
が盗まれていも、その accessToken
は使えなくなっている可能性が高いため、backend にアクセスすることを防ぐことになる.
3. refreshToken が盗まれると...
同じ refreshToken
がインターネット上を通ることになるので、refreshToken
を盗まれ、有効な accessToken
を発行することができてしまう.
なぜ refreshToken Rotation が必要なのか
refreshToken Rotation とは
refreshToken
を認証サーバに渡すときに、その refreshToken
は、無効になり使用できなくなる。そして新しい accessToken
と新しい refreshToken
を取得して、accessToken
と refreshToken
を更新することができる
refreshToken が盗まれると...
refreshToken
を盗まれていても、すでにその refreshToken
が使えなくなっている可能性があるので、有効な accessToken
を取得することができない.
無効な refreshToken
で accessToken
を取得しようとすると、そのセッション(全ての accessToken
と refreshToken
)は使えなり、自動的にログアウト状態になる
現状対策できないこと
refreshToken Rotation をしても1 つだけセッションが盗まれてしまう方法があります
ログアウト(セッションを切らない)をしないで放置してしまうこと
-
refreshToken
が無効化されずに、refreshToken
とaccessToken
が発行されるため、リソースにアクセスできるようになる.
上で説明した無効な refreshToken で accessToken を取得しようとすると、そのセッション(全ての accessToken と refreshToken)は使えなくる
という安全装置が作動しなくなるためである
まとめ
oauth2.0 を使う時は、
開発者
は、accessToken
とrefreshToken
を短くしましょうユーザ
は、ログアウト
をしっかりしましょう
次回は、
Nextjs(approuter)登場による token の管理のベストプラクティスについて
話そうと思います
Discussion
OAuth 2.0の代表的な使い方に ○○ ログインを挙げるのは避けるべきでしょう。
この通り、第3者のアプリケーションがあるユーザーのリソースへアクセスを可能にします。
その結果を用いてユーザー認証に利用するユースケースも実際存在しますがあくまで「OAuth 2.0を用いた認証機能の実装」であり、独自実装が多分に含まれています。
この○○ ログインという用途のために策定された仕様はOpenID ConnectやSAMLです。
この違いは実際のサービスの安全性に大きく関わることですので正しい理解が必要です。
ご指摘ありがとうございます。 OpenID ConnectとOAuth 2.0を混同して考えてしまい、誤解を招く表現となってしまいました。OAuth 2.0はリソースへのアクセス許可を委任するための仕組みであり、ユーザー認証を直接的に目的としたものではないという点を改めて認識しました。とても勉強になりました。今後はこの点を明確にして情報提供を行いたいと思います。
記事ありがとうございます。
一点お伺いしたいことがあり、コメントさせていただきました。
Auth0にアクセストークンが有効かを確認すると図の中であるのですが、こちらどういった機能で達成されましたでしょうか。
お手すきの際にご返信いただけますと幸いです。
よろしくお願いいたします。
<参考>
nest(ts)を使った実装
https://zenn.dev/naginagi124/articles/f28fadec5a661d
https://zenn.dev/naginagi124/articles/b24493a04d6ec4
基本的には公開鍵と秘密鍵の関係で確認を行います
返信ありがとうございます。
実装についてもありがとうございます。
JWKSを使用したアクセストークンの検証で、有効かの確認をしていたんですね。
お答えいただき、ありがとうございました!