0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1 学ぶ理由

・チーム開発でOAuthの外部連携のタスクをアサインしてもらったから。
・バックエンドエンジニアとして、今回はしっかりセキュアなものを作らねばならないから。

この記事で書くこと

  • OAuthの概要
  • 今後の実装で理解を深めたいことの整理

OAuthの概要

そもそもOAuthとは何かという話からなのだが、
OAuthの定義: パスワードを渡さずに**「アクセス権限」を委譲**するためのプロトコルである、ということになっている。
つまり、「認証」と「認可」としての「認可」プロトコルだということ!
(Oがプロトコルらしい)

 認証 (Authentication): 「あなたは誰ですか?」
〇認可 (Authorization): 「あなたはこれをする権限がありますか?」

ここをさらに全体像としては

名称 役割 補足・よくある使われ方
認証 (Authentication) 「この人は誰か?」を確認する 例:ID・パスワード、指紋、2FAなど
OAuth 2.0 「何を許可するか?」=認可(Authorization) GoogleやGitHubのAPI連携など
OpenID Connect (OIDC) OAuthの上に「認証の仕組み」を追加したもの 「Googleでログイン」などに使われる
JWT (JSON Web Token) トークン(鍵)の形式。OAuth/OIDCでよく使われる トークンを使って認証状態を保持する

であるとのこと。ゆえに一連の通りシステムでの外部連携などの際には、それぞれが関連し合っていなくてはならないことがわかる。

OAuthでの登場人物について

公式ドキュメントより、

アクター名 役割・立場 具体的な例 主な責務(何をする人か)
🧑‍💻 Resource Owner(リソースオーナー) 自分のデータの持ち主(=ユーザー本人) あなた(Googleアカウントの持ち主) - 自分のデータを他のアプリに共有してよいか「同意」する
- OAuthフローを開始する(ログイン・認可操作)
💼 Client(クライアントアプリ) 外部サービスにアクセスしたいアプリ あなたが開発しているWebアプリ / モバイルアプリ - Resource Ownerの代わりにデータを取得したい
- Authorization Serverを通じてトークンをもらう
🔐 Authorization Server(認可サーバー) アクセス許可やトークンを発行する公式サーバー GoogleのOAuthサーバー(accounts.google.com - ユーザー認証を行う(OIDCの場合)
- 同意画面を表示して認可を処理
- アクセストークン/IDトークンを発行する
🗄️ Resource Server(リソースサーバー) 実際のデータを保管しているAPIサーバー Google API(www.googleapis.com - アクセストークンを検証してアクセスを許可/拒否
- 許可された範囲内のデータを返す

となる。これらは立場から考えると、

観点 Resource Owner Client Authorization Server Resource Server
目的 自分のデータを安全に共有したい ユーザーのデータにアクセスしたい アクセス権を安全に発行したい データを安全に提供したい
信頼関係 Authorization Serverを信頼している Authorization Serverに登録されている Resource Ownerを認証する Authorization Serverから発行されたトークンを信頼
トークンとの関係 トークンの発行に同意 トークンを受け取り利用 トークンを発行 トークンを検証しデータを返す

これらの設定が必要になるのだ。

具体例で考える

リクエスト

curl -X POST https://oauth2.googleapis.com/token \
 -H "Content-Type: application/x-www-form-urlencoded" \
 -d "code=4/0Ad9I..." \
 -d "client_id=1234567890-abcdefg.apps.googleusercontent.com" \
 -d "client_secret=GOCSPX-xyz..." \
 -d "redirect_uri=https://yourapp.com/oauth2callback" \
 -d "grant_type=authorization_code"
  • code:googleから返された認可コード
  • client_id/client_secret:アプリのクレデンシャル
  • redirect_uri:google開発者コンソールで登録されたURLと一致
  • grant_type:標準的なOAuth認可コードフロー

レスポンス

{
  "access_token": "ya29.a0AfH6SMCQk...",
  "expires_in": 3599,
  "refresh_token": "1//0gA5abcdEf...",
  "scope": "openid email profile https://www.googleapis.com/auth/drive.readonly",
  "token_type": "Bearer",
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ij..."
}

id_tokenがある⇒OpenIDConnect対応

今後の深堀について

①フローの使い分け・把握

フロー名 主な用途 特徴 備考
Authorization Code Flow サーバーサイドWebアプリ 最も安全。認可コード→アクセストークン交換の2段階構成 PKCEを使うことでSPAでも利用可能
Implicit Flow 旧来のSPA向け(推奨されない) アクセストークンが直接ブラウザに返るため安全性が低い 現在は非推奨
Client Credentials Flow バックエンド間通信 ユーザーの同意不要。アプリ自身の資格情報で認可される サービス間APIで利用
Password Flow レガシー用途 ID/PWを直接送る。OAuthの思想に反する 原則非推奨

② トークンの使いわけ

トークン名 役割 使用場所 有効期限 補足
Access Token APIアクセス用のキー Resource Server 数分〜1時間程度 スコープに基づいてアクセス可能
Refresh Token アクセストークン再発行用 クライアント(安全に保管) 長期間(数日〜数週間) サーバーサイドでのみ使用が望ましい
ID Token 認証情報(ユーザー情報)を表す クライアント(OIDCのみ) Access Tokenと同等 JWT形式(署名付き)

OpenIdConnectのid_tokenに基づく sub(subjekt・ユーザー識別子)やemailなどが含まれていること

③ セキュリティ設計
OAuthを正しく使わないと、トークンの漏えいやなりすまし攻撃につながる。以下を常に意識したいと思う。

  • redirect_uri は必ずホワイトリストで制限する

  • client_secret はクライアント(ブラウザ)で扱わない(サーバー保管)

  • SPAではPKCE(Proof Key for Code Exchange)を必ず利用する

  • HTTPS通信を前提とする(トークンが平文で流れないように)

  • トークンを保存する場合は セキュアクッキー or サーバーセッション を利用する
    ⇒xssやcsrf対策

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?