はじめに
OAuth 2.0を学習する目的でアプリを作成しました。
アプリにGoogleログインやDiscordログインを実装したいけどいまいち仕組みがわかっていない、という方はぜひ読んでほしいです!
また、その際は実際にこのアプリを動かしながら理解することをおすすめします!
作ったもの

GoogleアカウントでログインするとGoogleアカウントのユーザー名、メールアドレスが表示されるアプリ
アプリを動かす
OAuthを理解するためには実際にこのアプリを使ってほしいのでそのセットアップ方法を書きます。
1. リポジトリをクローン
git clone git@github.com:Seripro/oauth-learning.git
cd oauth-learning
2. 環境変数を取得
Google Cloud コンソールからクライアントID、クライアントシークレットを取得してください。
また、コンソール上でコールバックURIをhttp://localhost:3000/callbackとしてください。
3. 環境変数を設定
ルートディレクトリに.envを作成し、取得したクライアントIDとクライアントシークレットを入れてください。
GOOGLE_CLIENT_ID=XXX
GOOGLE_CLIENT_SECRET=XXX
4. 依存関係のインストール
npm install
5. 開発サーバーの起動
npx tsx server.ts
起動したら、ブラウザで http://localhost:3000 を開いてください。
OAuth 2.0の仕組み
登場人物
-
ユーザー(Resource Owner)
例:Googleログインでログインしようとしている人
-
クライアント(アプリ)
例:Googleログイン機能を持つアプリ
-
Authorization Server
例:Googleの認可サーバー(Googleが管理しているもの)
-
Resource Server
例:Googleアカウントのユーザー名やメールアドレス、Google Driveのデータなどが保存されているサーバー(Googleが管理しているもの)
OAuth 2.0の流れ
ポイントは、「認可コードを受け取る → アクセストークンに交換する」という2段階になっていることです。
1. 認可と認可コードの取得
アプリ上で「Googleでログイン」をクリックすると、以下のクエリパラメータを含むURLにリダイレクトされAuthorization Serverにリクエストが送られます。
- クライアントID
- リダイレクトURI
- レスポンスタイプ
- スコープ(アプリ側で欲しい権限)
(クライアントIDはここのURLで露出するのでシークレットではありません)
すると、Googleのページにリダイレクトします。(ここまではアプリ側の処理)
このGoogle側の画面上でアカウントを選択すると、Authorization Serverは先ほどクエリパラメータで渡したリダイレクトURIへリダイレクトさせます。このURIにはクエリパラメータとして認可コード(ユーザーがアプリにGoogleのデータを渡すことを許可した証)が含まれます。
2. アクセストークンの取得
アプリ側はさっきのURIから認可コードを取得し、以下のリクエストボディをつけて再びAuthorization Serverにリクエストを送信します。(アクセストークンの取得)
- クライアントID
- クライアントシークレット
- グラントタイプ
- 認可コード
- リダイレクトURI
ここで渡すリダイレクトURIはリダイレクトが目的ではありません。以下をGoogle側が確かめるために渡します。
認可リクエスト時のリダイレクトURI(クエリパラメータ)
=
アクセストークン取得リクエスト時のリダイレクトURI(リクエストボディ)
=
コンソールに登録したリダイレクトURI
このリクエストが成功すればレスポンスとしてアクセストークンが返ります。
3. リソースへアクセス
アクセストークンが取得できたのであとはResource Serverからアプリで使いたいデータをもらうだけです。
ヘッダーにアクセストークンをつけてResource Server(Google)にリクエストを送り、返ってきたデータをアプリ内で利用します。

Googleアカウントのユーザー名、メールアドレスが表示されています。(上の画像は仮データです)
学び・気づき
実際に作ってみると理解しやすい
私はよくYouTubeやQiitaでアーキテクチャやプロトコルなど複雑なものの説明を見ます。
なんとなくこういうものがあるんだなあ、と知識にはなるのですが正直全く理解できていないです。(ドキュメントなどの文字だけで理解できる人は天才だと思います。)
今回対話形式でAIとこのアプリを作ってみたら、一つひとつの仕組みがどこに対応しているのかコードで理解することができ、ものすごく理解が深まりました。
フレームワークやライブラリなしだともっといい
今回このアプリを作る前に、OAuthを使った別のアプリのコードを見て勉強していました。しかし、そのアプリはNextAuthを使っていたため、どこがプロトコルの仕様で、どこがNextAuthの仕様なのか良くわからなくなってしまいました。
また、当たり前にログイン以外の機能も含まれるため、見るべきコード量も多く、大変でした。
ライブラリがないと実際に運用するアプリとしては心配だし、エラーハンドリングが雑だったりするけど、最初の理解としては、最小限の機能をスクラッチで作る今回のやり方がベストだと感じました。
参考文献
おわりに
サークルの先輩と勉強したのですが、知らないことたくさん知れました。


